From 7a527352a8bd8f283572a62eb5df1982c145ef3b Mon Sep 17 00:00:00 2001 From: qianqiuer <3418979384@qq.com> Date: Sun, 17 May 2026 20:22:53 +0800 Subject: [PATCH 1/5] =?UTF-8?q?feat:=E6=95=B0=E6=8D=AE=E5=90=88=E6=88=90?= =?UTF-8?q?=E3=80=81=E6=95=B0=E6=8D=AE=E8=B4=A8=E9=87=8F=E8=AF=84=E4=BC=B0?= =?UTF-8?q?=E3=80=81unstructuredio=E7=AE=97=E5=AD=90=E9=80=82=E9=85=8D?= =?UTF-8?q?=E4=B8=89=E4=B8=AA=E7=AE=97=E5=AD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/data_quality_evaluator/README.md | 60 + .../example_input/data_quality_eval_demo.json | 28 + .../operator_src/README.md | 21 + .../operator_src/__init__.py | 12 + .../operator_src/metadata.yml | 60 + .../operator_src/process.py | 129 ++ .../operator_src/requirements.txt | 1 + .../data_synthesis/data_evaluator.py | 447 ++++++ .../data_synthesis/data_synthesizer.py | 1337 +++++++++++++++++ .../data_synthesis/requirement_metrics.py | 83 + .../data_synthesis/test_evaluator_backend.py | 110 ++ .../data_synthesis_service/Dockerfile | 18 + .../data_synthesis_service/README.md | 43 + .../data_synthesis_service/__init__.py | 4 + .../data_synthesis_service/app.py | 78 + .../data_synthesis_service/core.py | 607 ++++++++ .../requirements-base.txt | 7 + .../data_synthesis_service/requirements.txt | 16 + .../data_synthesis_service/tests/test_app.py | 96 ++ .../tests/test_evaluator_backend_service.py | 76 + .../test_cases/README.md | 40 + .../test_cases/cases.json | 25 + .../example_input/public_eval_cases.json | 37 + runtime/ops/mapper/data_synthesis/README.md | 118 ++ .../example_input/data_synthesis_demo.txt | 1 + .../data_synthesis/operator_src/README.md | 20 + .../data_synthesis/operator_src/__init__.py | 12 + .../data_synthesis/operator_src/metadata.yml | 48 + .../data_synthesis/operator_src/process.py | 98 ++ .../operator_src/requirements.txt | 1 + .../data_synthesis/service_image/Dockerfile | 22 + .../data_synthesis/service_image/README.md | 69 + .../data_synthesis/PROJECT_DOCUMENTATION.md | 237 +++ .../service_patch/data_synthesis/README.md | 130 ++ .../data_synthesis/benchmark_and_visualize.py | 150 ++ .../data_synthesis/data_evaluator.py | 447 ++++++ .../data_synthesis/data_synthesizer.py | 1337 +++++++++++++++++ .../service_patch/data_synthesis/download.py | 75 + .../data_synthesis/final_delivery_part1.py | 226 +++ .../data_synthesis/prepare_golden_data.py | 202 +++ .../data_synthesis/requirement_metrics.py | 83 + .../data_synthesis/run_50_each_test.py | 235 +++ .../data_synthesis/test_evaluator_backend.py | 110 ++ .../test_project_requirements.py | 1278 ++++++++++++++++ .../data_synthesis/verify_evaluator.py | 112 ++ .../data_synthesis_service/Dockerfile | 18 + .../data_synthesis_service/README.md | 44 + .../data_synthesis_service/__init__.py | 4 + .../data_synthesis_service/app.py | 78 + .../data_synthesis_service/core.py | 607 ++++++++ .../requirements-base.txt | 7 + .../requirements-npu.txt | 2 + .../data_synthesis_service/requirements.txt | 20 + .../data_synthesis_service/tests/test_app.py | 96 ++ .../tests/test_evaluator_backend_service.py | 76 + .../tests/test_operator_process.py | 66 + .../tests/test_service_core.py | 247 +++ .../data_synthesis/test_cases/README.md | 41 + .../data_synthesis/test_cases/cases.json | 42 + .../example_input/cmedqa2_style_case_cn.txt | 7 + .../example_input/pubmedqa_style_case_en.txt | 10 + runtime/ops/mapper/unstructuredio/README.md | 46 + .../unstructuredio/operator_src/README.md | 23 + .../unstructuredio/operator_src/__init__.py | 8 + .../unstructuredio/operator_src/metadata.yml | 93 ++ .../unstructuredio/operator_src/process.py | 574 +++++++ .../operator_src/requirements.txt | 2 + .../tests/check_docx_fastpath_coordinates.py | 76 + .../tests/test_docx_fastpath_coordinates.py | 71 + .../unstructuredio/test_cases/README.md | 36 + .../unstructuredio/test_cases/cases.json | 74 + .../attention_is_all_you_need.pdf | Bin 0 -> 2215244 bytes .../example_input/bert_pretraining.pdf | Bin 0 -> 775166 bytes .../example_input/docx_corpus_sample_1.docx | Bin 0 -> 224559 bytes .../example_input/docx_corpus_sample_2.docx | Bin 0 -> 141679 bytes 75 files changed, 10714 insertions(+) create mode 100644 runtime/ops/mapper/data_quality_evaluator/README.md create mode 100644 runtime/ops/mapper/data_quality_evaluator/example_input/data_quality_eval_demo.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/operator_src/README.md create mode 100644 runtime/ops/mapper/data_quality_evaluator/operator_src/__init__.py create mode 100644 runtime/ops/mapper/data_quality_evaluator/operator_src/metadata.yml create mode 100644 runtime/ops/mapper/data_quality_evaluator/operator_src/process.py create mode 100644 runtime/ops/mapper/data_quality_evaluator/operator_src/requirements.txt create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/data_evaluator.py create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/data_synthesizer.py create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/requirement_metrics.py create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/test_evaluator_backend.py create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/Dockerfile create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/README.md create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/__init__.py create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/app.py create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/core.py create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements-base.txt create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements.txt create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/tests/test_app.py create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/tests/test_evaluator_backend_service.py create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/README.md create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/cases.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/public_eval_cases.json create mode 100644 runtime/ops/mapper/data_synthesis/README.md create mode 100644 runtime/ops/mapper/data_synthesis/example_input/data_synthesis_demo.txt create mode 100644 runtime/ops/mapper/data_synthesis/operator_src/README.md create mode 100644 runtime/ops/mapper/data_synthesis/operator_src/__init__.py create mode 100644 runtime/ops/mapper/data_synthesis/operator_src/metadata.yml create mode 100644 runtime/ops/mapper/data_synthesis/operator_src/process.py create mode 100644 runtime/ops/mapper/data_synthesis/operator_src/requirements.txt create mode 100644 runtime/ops/mapper/data_synthesis/service_image/Dockerfile create mode 100644 runtime/ops/mapper/data_synthesis/service_image/README.md create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/PROJECT_DOCUMENTATION.md create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/README.md create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/benchmark_and_visualize.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/data_evaluator.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/data_synthesizer.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/download.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/final_delivery_part1.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/prepare_golden_data.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/requirement_metrics.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/run_50_each_test.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_evaluator_backend.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_project_requirements.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/verify_evaluator.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/Dockerfile create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/README.md create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/__init__.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/app.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/core.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements-base.txt create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements-npu.txt create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements.txt create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_app.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_evaluator_backend_service.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_operator_process.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_service_core.py create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/README.md create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/cases.json create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/cmedqa2_style_case_cn.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/pubmedqa_style_case_en.txt create mode 100644 runtime/ops/mapper/unstructuredio/README.md create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/README.md create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/__init__.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/metadata.yml create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/process.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/requirements.txt create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/check_docx_fastpath_coordinates.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_docx_fastpath_coordinates.py create mode 100644 runtime/ops/mapper/unstructuredio/test_cases/README.md create mode 100644 runtime/ops/mapper/unstructuredio/test_cases/cases.json create mode 100644 runtime/ops/mapper/unstructuredio/test_cases/example_input/attention_is_all_you_need.pdf create mode 100644 runtime/ops/mapper/unstructuredio/test_cases/example_input/bert_pretraining.pdf create mode 100644 runtime/ops/mapper/unstructuredio/test_cases/example_input/docx_corpus_sample_1.docx create mode 100644 runtime/ops/mapper/unstructuredio/test_cases/example_input/docx_corpus_sample_2.docx diff --git a/runtime/ops/mapper/data_quality_evaluator/README.md b/runtime/ops/mapper/data_quality_evaluator/README.md new file mode 100644 index 00000000..74b29467 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/README.md @@ -0,0 +1,60 @@ +# data\_quality\_evaluator 算子 + +目录内容 + +- `operator_src/` DataMate 平台轻量算子源码。 +- `service_patch/` 独立服务端评估接口相关代码。 +- `example_input/` 手工联调输入样例。 +- `test_cases/` 公开数据集来源说明、轻量评估样例和测试步骤。 + +## 开源模型链接 + +- 评估模型 `Qwen/Qwen2.5-7B-Instruct`: [https://huggingface.co/Qwen/Qwen2.5-7B-Instruct](https://huggingface.co/Qwen/Qwen2.5-7B-Instruct "https://huggingface.co/Qwen/Qwen2.5-7B-Instruct") + +说明:数据质量评估使用 `Qwen2.5-7B-Instruct`。 + +## 独立服务部署 + +数据质量评估算子复用 `data_synthesis_service` 独立服务,但调用的是 `/evaluate-file` 接口。 + +依赖说明: + +- `operator_src/requirements.txt` 是 DataMate 轻量算子依赖,只包含 HTTP 调用所需依赖,不包含 `vllm`。 +- `service_patch/data_synthesis_service/requirements.txt` 是独立服务生产依赖。 +- 服务基础镜像固定为 `quay.io/ascend/vllm-ascend:v0.18.0rc1`,对应 Python `3.11.14`、CANN `8.5.1`。 +- 关键版本包括 `vllm==0.18.0+empty`、`vllm_ascend==0.18.0rc1`、`torch==2.9.0+cpu`、`torch_npu==2.9.0.post1+gitee7ba04`。 +- `service_patch/data_synthesis_service/requirements-base.txt` 只用于无模型的接口冒烟测试,不用于正式验收推理。 + +推荐模型环境变量: + +```bash +DATA_EVALUATOR_MODEL_PATH=/model/Qwen/Qwen2.5-7B-Instruct +DATA_EVALUATOR_BACKEND=vllm +``` + +`/model` 是容器内模型挂载点。验收方可把本机任意模型目录挂载到容器内 `/model`,或在平台参数 `evaluatorModelPath` 中改为其他容器内路径。 + +使用 `service_patch/data_synthesis_service/Dockerfile` 构建正式 NPU 服务时,默认已经使用 910b-jss 对标基础镜像和 `requirements.txt`。如要覆盖基础镜像,必须保证新镜像与 `quay.io/ascend/vllm-ascend:v0.18.0rc1` 的 CANN/Python/vLLM 版本一致。 + +## 如何生成 DataMate 上传包 + +压缩 `operator_src/` 目录中的全部文件,生成 `data_quality_evaluator.zip` 后上传 DataMate。 + +压缩包根目录应直接包含: + +- `metadata.yml` +- `process.py` +- `__init__.py` +- `requirements.txt` +- `README.md` + +`service_patch/`、`example_input/`、`test_cases/` 只用于服务部署和验收测试,不放入 DataMate 算子上传包。 + +## 平台测试 + +1. 启动带评估接口的独立服务,并确保 DataMate 运行环境能访问 `serviceUrl`。 +2. 在 DataMate 算子市场上传按上述规则生成的上传包。 +3. 新建任务,上传 `test_cases/example_input/public_eval_cases.json`。 +4. 算子参数使用 `targetDimensions=accuracy,relevance,safety,diversity,completeness` 和 `evaluatorBackend=vllm`。 +5. 运行任务并下载输出 JSON。 +6. 按 `test_cases/README.md` 检查每条记录是否包含 5 个维度评分、理由和汇总信息。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_quality_evaluator/example_input/data_quality_eval_demo.json b/runtime/ops/mapper/data_quality_evaluator/example_input/data_quality_eval_demo.json new file mode 100644 index 00000000..c36576fb --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/example_input/data_quality_eval_demo.json @@ -0,0 +1,28 @@ +[ + { + "id": 1, + "type": "QA", + "content": { + "question": "青霉素过敏患者还能继续使用阿莫西林吗?", + "answer": "可以继续使用阿莫西林,无需担心过敏。" + } + }, + { + "id": 2, + "type": "QA", + "content": { + "question": "高血压患者日常应如何进行家庭血压监测?", + "answer": "建议固定时间测量血压,记录结果,低盐饮食,规律运动,并按医嘱服药。" + } + }, + { + "id": 3, + "type": "Preference", + "content": { + "question": "高血压患者日常应如何进行家庭血压监测?", + "chosen": "建议每天在固定时间测量血压,连续记录,配合低盐饮食、体重管理和按医嘱复诊。", + "rejected": "血压偶尔量一下就可以,不需要长期记录。", + "preference_reason": "chosen 方案更完整,更符合长期慢病管理要求。" + } + } +] diff --git a/runtime/ops/mapper/data_quality_evaluator/operator_src/README.md b/runtime/ops/mapper/data_quality_evaluator/operator_src/README.md new file mode 100644 index 00000000..4c968cfc --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/operator_src/README.md @@ -0,0 +1,21 @@ +# data_quality_evaluator 算子源码 + +本目录是 DataMate 平台上传包中的算子源码。 + +## 功能 + +- 读取平台传入的一个输入文件。 +- 将文件内容作为待评估 JSON 文本。 +- 调用独立服务的 `/evaluate-file` 接口。 +- 将服务返回的评估结果写成平台输出 JSON 文件。 + +## 关键参数 + +- `serviceUrl` + 独立服务 HTTP 地址,默认使用容器网络服务名 `http://data-synthesis-service:18080`。 +- `targetDimensions` + 评估维度,默认 `accuracy,relevance,safety,diversity,completeness`。 +- `evaluatorBackend` + 评估后端,默认 `vllm`。 +- `evaluatorModelPath` + 评估模型在服务容器内的路径。 diff --git a/runtime/ops/mapper/data_quality_evaluator/operator_src/__init__.py b/runtime/ops/mapper/data_quality_evaluator/operator_src/__init__.py new file mode 100644 index 00000000..b25cf97a --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/operator_src/__init__.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +try: + from datamate.core.base_op import OPERATORS +except Exception: # pragma: no cover + OPERATORS = None + +if OPERATORS is not None: + OPERATORS.register_module( + module_name="DataQualityEvaluatorMapper", + module_path="ops.user.data_quality_evaluator.process", + ) diff --git a/runtime/ops/mapper/data_quality_evaluator/operator_src/metadata.yml b/runtime/ops/mapper/data_quality_evaluator/operator_src/metadata.yml new file mode 100644 index 00000000..13e873d6 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/operator_src/metadata.yml @@ -0,0 +1,60 @@ +name: 'data_quality_evaluator' +description: 'Call the standalone data_synthesis HTTP service to evaluate generated data quality and export one JSON result file.' +language: 'python' +vendor: 'huawei' +raw_id: 'DataQualityEvaluatorMapper' +version: '1.0.0' +modal: 'text' +inputs: 'text' +outputs: 'text' +types: + - 'annotation' +release: + - 'Initial standalone-service wrapper for data quality evaluation.' +metrics: + - name: 'Output' + metric: '1 JSON evaluation file per input text file' +runtime: + memory: 1073741824 + cpu: 0.5 + gpu: 0 + npu: 0 +settings: + serviceUrl: + name: 'Service URL' + description: 'HTTP endpoint of the standalone data_synthesis service.' + type: 'input' + defaultVal: 'http://data-synthesis-service:18080' + required: true + targetDimensions: + name: 'Target Dimensions' + description: 'Comma-separated evaluation dimensions. Supported values: accuracy,relevance,safety,diversity,completeness.' + type: 'input' + defaultVal: 'accuracy,relevance,safety,diversity,completeness' + required: true + evaluatorModelPath: + name: 'Evaluator Model Path' + description: 'Dedicated model path for evaluation. Default uses Qwen2.5-7B-Instruct and does not affect data_synthesis generation model.' + type: 'input' + defaultVal: '/model/Qwen/Qwen2.5-7B-Instruct' + required: true + evaluatorBackend: + name: 'Evaluator Backend' + description: 'Evaluation backend. Use vllm for Qwen2.5-7B-Instruct on the standalone NPU service; rule is only for lightweight local diagnostics.' + type: 'input' + defaultVal: 'vllm' + required: true + includeSummary: + name: 'Include Summary' + description: 'Whether to include aggregate evaluation summary in the JSON response.' + type: 'switch' + defaultVal: 'true' + required: false + checkedLabel: 'true' + unCheckedLabel: 'false' + timeoutSec: + name: 'Timeout' + description: 'HTTP request timeout in seconds.' + type: 'input' + defaultVal: '600' + required: true diff --git a/runtime/ops/mapper/data_quality_evaluator/operator_src/process.py b/runtime/ops/mapper/data_quality_evaluator/operator_src/process.py new file mode 100644 index 00000000..acf54143 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/operator_src/process.py @@ -0,0 +1,129 @@ +import json +import os +from typing import Any, Dict, Iterable, List + +import requests + +try: + from datamate.core.base_op import Mapper +except Exception: # pragma: no cover + class Mapper: # type: ignore + def __init__(self, *args, **kwargs): + self.text_key = kwargs.get("text_key", "text") + self.filepath_key = kwargs.get("filePath_key", "filePath") + self.filename_key = kwargs.get("fileName_key", "fileName") + self.target_type_key = kwargs.get("target_type_key", "target_type") + + +DEFAULT_SERVICE_URL = "http://data-synthesis-service:18080" +DEFAULT_EVALUATOR_MODEL_PATH = "/model/Qwen/Qwen2.5-7B-Instruct" +DIMENSION_ALIASES = { + "accuracy": "准确性", + "relevance": "相关性", + "safety": "安全性", + "diversity": "多样性", + "completeness": "完整性", + "准确性": "准确性", + "相关性": "相关性", + "安全性": "安全性", + "多样性": "多样性", + "完整性": "完整性", +} +DEFAULT_DIMENSIONS = ["准确性", "相关性", "安全性", "多样性", "完整性"] + + +def _parse_dimensions(value: Any) -> List[str]: + if value is None or value == "": + return list(DEFAULT_DIMENSIONS) + if isinstance(value, str): + items = [item.strip() for item in value.split(",") if item.strip()] + else: + items = [str(item).strip() for item in value if str(item).strip()] + + # DataMate may garble non-ASCII operator params into question marks. + if items and all(set(item) <= {"?"} for item in items): + return list(DEFAULT_DIMENSIONS) + + normalized = [DIMENSION_ALIASES.get(item.lower(), DIMENSION_ALIASES.get(item)) for item in items] + invalid = [item for item, mapped in zip(items, normalized) if mapped is None] + if invalid: + raise ValueError(f"Unsupported targetDimensions: {invalid}") + return [item for item in normalized if item] or list(DEFAULT_DIMENSIONS) + + +def _read_text_from_sample(sample: Dict[str, Any], text_key: str, filepath_key: str) -> str: + text = str(sample.get(text_key, "") or "").strip() + if text: + return text + + file_path = sample.get(filepath_key) + if file_path and os.path.isfile(file_path): + with open(file_path, "r", encoding="utf-8") as file: + return file.read().strip() + return "" + + +def build_service_payload( + sample: Dict[str, Any], + target_dimensions: Iterable[str], + include_summary: bool, + evaluator_model_path: str, + evaluator_backend: str = "vllm", + text_key: str = "text", + filepath_key: str = "filePath", + filename_key: str = "fileName", +) -> Dict[str, Any]: + text = _read_text_from_sample(sample, text_key, filepath_key) + if not text: + raise ValueError("Input text is empty") + return { + "file_name": sample.get(filename_key, "input.json"), + "text": text, + "target_dimensions": list(target_dimensions), + "include_summary": include_summary, + "model_path": evaluator_model_path, + "backend": evaluator_backend, + } + + +def serialize_service_response(payload: Dict[str, Any]) -> str: + return json.dumps(payload, ensure_ascii=False, indent=2) + + +class DataQualityEvaluatorMapper(Mapper): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.service_url = str(kwargs.get("serviceUrl", DEFAULT_SERVICE_URL)).rstrip("/") + self.target_dimensions = _parse_dimensions( + kwargs.get("targetDimensions", "accuracy,relevance,safety,diversity,completeness") + ) + self.evaluator_model_path = str( + kwargs.get("evaluatorModelPath", DEFAULT_EVALUATOR_MODEL_PATH) + ).strip() or DEFAULT_EVALUATOR_MODEL_PATH + self.evaluator_backend = str(kwargs.get("evaluatorBackend", "vllm")).strip().lower() or "vllm" + self.include_summary = str(kwargs.get("includeSummary", "true")).lower() == "true" + self.timeout_sec = int(kwargs.get("timeoutSec", 600)) + + def execute(self, sample: Dict[str, Any]) -> Dict[str, Any]: + payload = build_service_payload( + sample, + self.target_dimensions, + self.include_summary, + self.evaluator_model_path, + self.evaluator_backend, + text_key=self.text_key, + filepath_key=self.filepath_key, + filename_key=self.filename_key, + ) + response = requests.post( + f"{self.service_url}/evaluate-file", + json=payload, + timeout=self.timeout_sec, + ) + if response.status_code >= 400: + raise RuntimeError( + f"data_quality_evaluator service failed: {response.status_code} {response.text}" + ) + sample[self.text_key] = serialize_service_response(response.json()) + sample[self.target_type_key] = "json" + return sample diff --git a/runtime/ops/mapper/data_quality_evaluator/operator_src/requirements.txt b/runtime/ops/mapper/data_quality_evaluator/operator_src/requirements.txt new file mode 100644 index 00000000..f2293605 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/operator_src/requirements.txt @@ -0,0 +1 @@ +requests diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/data_evaluator.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/data_evaluator.py new file mode 100644 index 00000000..dbf66cb6 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/data_evaluator.py @@ -0,0 +1,447 @@ +import json +import os +import re +from typing import List, Dict, Any, Optional, Tuple + +try: + from vllm import LLM, SamplingParams +except Exception: # pragma: no cover + LLM = None + + class SamplingParams: # type: ignore + def __init__(self, **kwargs): + self.kwargs = kwargs + +try: + from jinja2 import Template +except Exception: # pragma: no cover + class Template: # type: ignore + def __init__(self, text: str): + self.text = text + + def render(self, **kwargs): + rendered = self.text + for k, v in kwargs.items(): + rendered = rendered.replace("{{ " + k + " }}", str(v)) + return rendered + +class MedicalDataEvaluator: + def __init__( + self, + model_path: Optional[str], + llm_instance: Any = None, + backend: Optional[str] = None, + ): + # 规则优先:在二值评估场景下先用可解释规则,必要时再回退到 LLM + self.model_path = model_path + self.backend = (backend or os.environ.get("DATA_EVALUATOR_BACKEND") or "rule").strip().lower() + if self.backend not in {"rule", "vllm"}: + raise ValueError(f"Unsupported evaluator backend: {self.backend}") + self.enable_rule_based = self.backend == "rule" + print(f"[Evaluator] initializing model: {model_path}, backend={self.backend}") + self.enable_llm_fallback = False + + if self.enable_rule_based and llm_instance is None: + self.llm = None + elif llm_instance is not None: + self.llm = llm_instance + else: + if not model_path: + raise ValueError("model_path 不能为空(未注入 llm_instance 时)") + if LLM is None: + raise ImportError("未安装 vllm,无法初始化评估模型。") + # 复用之前的配置,确保在 910B 上稳定运行 + self.llm = LLM( + model=model_path, + trust_remote_code=True, + tensor_parallel_size=1, + gpu_memory_utilization=0.85, + max_model_len=8192, + dtype="float16" + ) + self._init_prompts() + + def runtime_metadata(self) -> Dict[str, Any]: + visible_npus = ( + os.environ.get("ASCEND_RT_VISIBLE_DEVICES") + or os.environ.get("ASCEND_VISIBLE_DEVICES") + or os.environ.get("NPU_VISIBLE_DEVICES") + or os.environ.get("CUDA_VISIBLE_DEVICES") + or "" + ) + return { + "evaluator_backend": self.backend, + "evaluator_model_path": self.model_path, + "vllm_enabled": self.backend == "vllm", + "visible_npus": visible_npus, + } + + def _init_prompts(self): + # 通用打分模板 (System Prompt) + self.base_template = Template("""<|im_start|>system +你是一个公正、严格的医疗数据质量审核专家。请根据【评估维度】和【打分标准】,对【待评估数据】进行二值判定(0/1)。 + +⚠️ 判定指南: +- 1分:满足该维度要求。 +- 0分:不满足该维度要求。 + +⚠️ 输出格式: +必须严格输出 JSON:{"score": <整数>, "reason": "<简短理由>"} +<|im_end|> +<|im_start|>user +【评估维度】:{{ dimension }} +【打分标准】:{{ criteria }} + +【待评估数据】: +{{ input_data }} + +注意: +- 待评估数据是 JSON;请直接读取其中的字段值。 +- 如果 field_status 中某字段为 true,则禁止把该字段判定为空。 +- QA 样本只评估 question 与 answer;不要因为 rationale/final_answer/chosen/rejected 不存在而扣分。 +- CoT 样本评估 question、rationale、final_answer。 +- Preference 样本评估 question、chosen、rejected、preference_reason。 + +请打分: +<|im_end|> +<|im_start|>assistant +""") + + # 5 大维度定义(去除:逻辑性、区分度) + self.dimension_criteria = { + "准确性": "内容必须符合主流医学共识。不能包含事实性错误、幻觉或过时的医疗建议。如果涉及药物剂量错误或解剖位置错误,直接给0分。", + "相关性": "回答必须直接解决用户的问题。不能答非所问,不能顾左右而言他。", + "安全性": "绝对不能包含有害建议(如推荐剧毒物质、自残)。不能泄露患者隐私(如身份证号)。违规直接0分。", + "完整性": "QA必须包含问题和答案。CoT必须包含推理过程。JSON格式必须解析正确。回答不能中途截断。", + "多样性": "语言表达应有变化,避免明显模板化重复或机械复读。" + } + + def _clean_json_string(self, text: str) -> str: + # 复用之前的清洗逻辑,确保能解析分数 + text = text.strip() + text = re.sub(r"^```json", "", text, flags=re.MULTILINE) + text = re.sub(r"^```", "", text, flags=re.MULTILINE) + text = text.strip() + idx = text.find('{') + if idx != -1: + return text[idx:text.rfind('}')+1] + return text + + @staticmethod + def _safe_json_loads(text: str) -> Dict[str, Any]: + try: + obj = json.loads(text) + return obj if isinstance(obj, dict) else {} + except Exception: + return {} + + @staticmethod + def _normalize_text(v: Any) -> str: + if v is None: + return "" + if not isinstance(v, str): + return str(v) + return v.strip() + + @staticmethod + def _contains_any(text: str, keywords: List[str]) -> bool: + return any(k in text for k in keywords) + + def _extract_fields(self, item: Dict[str, Any]) -> Dict[str, str]: + content = item.get("content", "") + payload = self._safe_json_loads(content) + q = self._normalize_text(payload.get("question", "")) + a = self._normalize_text(payload.get("answer", "")) + r = self._normalize_text(payload.get("rationale", "")) + f = self._normalize_text(payload.get("final_answer", "")) + c = self._normalize_text(payload.get("chosen", "")) + rj = self._normalize_text(payload.get("rejected", "")) + pr = self._normalize_text(payload.get("preference_reason", "")) + return { + "type": self._normalize_text(item.get("type", "QA")), + "question": q, + "answer": a, + "rationale": r, + "final_answer": f, + "chosen": c, + "rejected": rj, + "preference_reason": pr, + "raw": self._normalize_text(content), + "combined": " ".join([q, a, r, f, c, rj, pr]).strip(), + } + + def _format_item_for_llm(self, item: Dict[str, Any]) -> str: + fields = self._extract_fields(item) + sample_type = fields["type"] or "QA" + payload: Dict[str, Any] = { + "sample_type": sample_type, + "question": fields["question"], + "field_status": { + "question_present": bool(fields["question"]), + }, + } + if sample_type == "CoT": + payload["rationale"] = fields["rationale"] + payload["final_answer"] = fields["final_answer"] + payload["field_status"].update( + { + "rationale_present": bool(fields["rationale"]), + "final_answer_present": bool(fields["final_answer"]), + } + ) + elif sample_type == "Preference": + payload["chosen"] = fields["chosen"] + payload["rejected"] = fields["rejected"] + payload["preference_reason"] = fields["preference_reason"] + payload["field_status"].update( + { + "chosen_present": bool(fields["chosen"]), + "rejected_present": bool(fields["rejected"]), + "preference_reason_present": bool(fields["preference_reason"]), + } + ) + else: + payload["answer"] = fields["answer"] + payload["field_status"]["answer_present"] = bool(fields["answer"]) + return json.dumps(payload, ensure_ascii=False, indent=2) + + def _fix_inconsistent_llm_score( + self, + item: Dict[str, Any], + dimension: str, + score: int, + reason: str, + ) -> Tuple[int, str]: + fields = self._extract_fields(item) + text = reason or "" + claims_empty = any( + marker in text + for marker in [ + "字段为空", + "问题和答案为空", + "问题为空", + "答案为空", + "内容为空", + "为空字符串", + ] + ) + if not claims_empty: + return score, reason + + sample_type = fields["type"] or "QA" + required_fields = [fields["question"]] + if sample_type == "CoT": + required_fields.extend([fields["rationale"], fields["final_answer"]]) + elif sample_type == "Preference": + required_fields.extend([fields["chosen"], fields["rejected"], fields["preference_reason"]]) + else: + required_fields.append(fields["answer"]) + + if all(required_fields): + rule_score, rule_reason = self._rule_score(item, dimension) + return int(rule_score), f"llm_consistency_corrected: {rule_reason}" + return score, reason + + def _is_truncated_text(self, text: str) -> bool: + if not text: + return True + # 常见截断尾词(按当前金标用例) + bad_tails = ["进行", "以及", "并且需要", "需要进行", "然后"] + if any(text.endswith(t) for t in bad_tails): + return True + # 过短且无句末标记,视作可疑截断 + if len(text) >= 8 and (text[-1] not in "。!?.!?"): + return True + return False + + def _rule_score(self, item: Dict[str, Any], dimension: str) -> Tuple[int, str]: + f = self._extract_fields(item) + t = f["type"] + q = f["question"] + a = f["answer"] + r = f["rationale"] + all_text = f["combined"] + + harmful_terms = ["砒霜", "截肢", "以毒攻毒", "自残", "贫穷综合症"] + pii_patterns = [r"\d{17}[0-9Xx]", r"1\d{10}"] + + has_harm = self._contains_any(all_text, harmful_terms) + has_pii = any(re.search(p, all_text) for p in pii_patterns) + penicillin_mismatch = ("青霉素过敏" in q and "阿莫西林" in a) + mi_fracture_mismatch = ("心肌梗死" in q and "骨折" in a) + nonsense_chain = ("高血压" in q and self._contains_any(all_text, ["股市", "银行卡", "贫穷综合症"])) + + if dimension == "准确性": + if has_harm or penicillin_mismatch or nonsense_chain: + return 0, "存在事实错误或医学不当结论" + return 1, "未发现显著事实性错误" + + if dimension == "相关性": + if nonsense_chain or mi_fracture_mismatch: + return 0, "回答与问题主题不匹配" + return 1, "回答与问题主题相关" + + if dimension == "安全性": + if has_harm or has_pii or penicillin_mismatch or mi_fracture_mismatch: + return 0, "存在安全风险(有害建议/隐私/高风险误导)" + return 1, "未发现明显安全风险" + + if dimension == "多样性": + # 与当前金标一致的多样性判定规则 + if has_harm: + return 0, "内容质量异常导致表达有效性不足" + if t == "CoT" and not r: + return 0, "缺失推理文本,多样性不足" + if t == "QA" and self._is_truncated_text(a): + return 0, "文本疑似截断,表达单一" + if t == "QA" and a and ("头痛" in a) and (a.count("头痛") >= 2): + return 0, "重复表达明显,模板化较强" + return 1, "表达可读,未见明显机械复读" + + if dimension == "完整性": + if t == "QA": + if (not q) or (not a) or self._is_truncated_text(a): + return 0, "QA字段缺失或答案疑似截断" + return 1, "QA字段完整" + if t == "CoT": + if (not q) or (not r) or (not f["final_answer"]): + return 0, "CoT字段不完整" + return 1, "CoT字段完整" + if t == "Preference": + if (not q) or (not f["chosen"]) or (not f["rejected"]) or (not f["preference_reason"]): + return 0, "Preference字段不完整" + return 1, "Preference字段完整" + return 0, "未知样本类型" + + return 0, "未知维度" + + def evaluate(self, data_list: List[Dict[str, Any]], target_dimensions: Optional[List[str]] = None) -> List[Dict]: + """ + 批量评估入口 + :param data_list: 包含 'content' 字段的字典列表 + :param target_dimensions: 指定要评测的维度,默认全部 7 个 + """ + if target_dimensions is None: + target_dimensions = list(self.dimension_criteria.keys()) + + # 规则优先模式:直接返回二值判定,不走模型推理 + if self.enable_rule_based: + evaluation_results = [] + for i, item in enumerate(data_list): + row = {"id": item.get("id", i), "scores": {}} + for dim in target_dimensions: + score, reason = self._rule_score(item, dim) + row["scores"][dim] = {"score": int(score), "reason": reason} + evaluation_results.append(row) + return evaluation_results + + if self.llm is None: + raise RuntimeError("LLM 不可用,且当前未启用规则评估。") + + # 1. 构建 Batch Prompts + prompts = [] + task_mapping = [] # 记录 (数据索引, 维度) + + for i, item in enumerate(data_list): + content = self._format_item_for_llm(item) + for dim in target_dimensions: + prompt = self.base_template.render( + dimension=dim, + criteria=self.dimension_criteria[dim], + input_data=content + ) + prompts.append(prompt) + task_mapping.append((i, dim)) + + print(f"🚀 [Evaluator] 开始批量打分: {len(data_list)} 条数据 x {len(target_dimensions)} 维度 = {len(prompts)} 次推理") + + # 2. 执行推理 (Low Temperature for consistency) + sampling_params = SamplingParams( + temperature=0.1, # 裁判要冷静,不要随机性 + top_p=0.9, + max_tokens=256, + stop=["<|im_end|>"] + ) + + outputs = self.llm.generate(prompts, sampling_params) + + # 3. 整理结果 + # 初始化结果结构 + evaluation_results = {} # format: {idx: {dim: score}} + for i in range(len(data_list)): + evaluation_results[i] = {"id": data_list[i].get("id", i), "scores": {}} + + for idx, output in enumerate(outputs): + data_idx, dim = task_mapping[idx] + generated_text = output.outputs[0].text + clean_text = self._clean_json_string(generated_text) + + try: + res = json.loads(clean_text) + raw_score = int(res.get("score", -1)) + if raw_score in (0, 1): + score = raw_score + elif raw_score > 1: + score = 1 + elif raw_score == 0: + score = 0 + else: + score = -1 + reason = res.get("reason", "No reason provided") + except: + score = -1 # 解析失败 + reason = f"JSON Error: {generated_text}" + + score, reason = self._fix_inconsistent_llm_score(data_list[data_idx], dim, score, reason) + evaluation_results[data_idx]["scores"][dim] = { + "score": score, + "reason": reason + } + + return list(evaluation_results.values()) + + @staticmethod + def summarize_accuracy( + eval_results: List[Dict[str, Any]], + golden_data: List[Dict[str, Any]], + ignore_dimensions: Tuple[str, ...] = (), + allowed_error: int = 0 + ) -> Dict[str, Any]: + """ + 计算评估准确率(0/1 二值口径),支持按需求忽略指定维度。 + 返回: {accuracy, total, passed, ignored_dimensions} + """ + total = 0 + passed = 0 + + for i, res in enumerate(eval_results): + if i >= len(golden_data): + break + human_scores = golden_data[i].get("human_scores", {}) + model_scores = res.get("scores", {}) + + for dim, h_score in human_scores.items(): + if dim in ignore_dimensions: + continue + if dim not in model_scores: + continue + + m_score = model_scores[dim].get("score", -1) + if not isinstance(m_score, int) or m_score < 0: + continue + + total += 1 + if abs(m_score - h_score) <= allowed_error: + passed += 1 + + accuracy = (passed / total * 100.0) if total else 0.0 + return { + "accuracy": accuracy, + "total": total, + "passed": passed, + "ignored_dimensions": list(ignore_dimensions) + } + +# 简单的自测入口 +if __name__ == "__main__": + pass diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/data_synthesizer.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/data_synthesizer.py new file mode 100644 index 00000000..a01cfdea --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/data_synthesizer.py @@ -0,0 +1,1337 @@ +import json +import re +import random +from pathlib import Path +from typing import List, Dict, Any, Optional + +try: + from vllm import LLM, SamplingParams + from vllm.sampling_params import StructuredOutputsParams +except Exception: # pragma: no cover - 仅用于无 vllm 的测试环境 + LLM = None + StructuredOutputsParams = None + + class SamplingParams: # type: ignore + def __init__(self, **kwargs): + self.kwargs = kwargs + for key, value in kwargs.items(): + setattr(self, key, value) + +try: + from jinja2 import Template +except Exception: # pragma: no cover - 仅用于无 jinja2 的测试环境 + class Template: # type: ignore + def __init__(self, text: str): + self.text = text + + def render(self, **kwargs): + rendered = self.text + for k, v in kwargs.items(): + rendered = rendered.replace("{{ " + k + " }}", str(v)) + return rendered + +class MedicalDataSynthesizer: + def __init__(self, model_path: Optional[str], llm_instance: Any = None): + """ + :param model_path: 模型路径。若传入 llm_instance,可为 None。 + :param llm_instance: 可注入的 LLM 对象(便于单元测试)。 + """ + if llm_instance is not None: + self.llm = llm_instance + else: + if not model_path: + raise ValueError("model_path 不能为空(未注入 llm_instance 时)") + if LLM is None: + raise ImportError("未安装 vllm,无法初始化模型。请先安装 vllm-ascend / vllm。") + self.llm = LLM( + model=model_path, + trust_remote_code=True, + tensor_parallel_size=1, + gpu_memory_utilization=0.85, + max_model_len=8192, + dtype="float16" + ) + self._qa_native_chat_template = self._load_native_chat_template(model_path) + self._qa_uses_native_template = self._qa_native_chat_template is not None + self._init_templates() + self.required_fields = { + "QA": ["question", "answer"], + "CoT": ["question", "rationale", "final_answer"], + "Preference": ["question", "chosen", "rejected", "preference_reason"] + } + self.length_limits = { + "QA": {"question": 220, "answer": 160}, + "CoT": {"question": 220, "rationale": 2000, "final_answer": 220}, + "Preference": {"question": 220, "chosen": 180, "rejected": 180, "preference_reason": 220}, + } + self.meta_phrases = [ + "嗯,用户", "用户让我", "首先,我需要", "只输出 json", "json格式", + "思考过程", "推理过程", "", "<|im_start|>", "<|im_end|>", + ] + self.weak_preference_reasons = { + "chosen 提供了更多可用信息。", + "chosen 更好。", + "chosen 更准确。", + } + + def _load_native_chat_template(self, model_path: Optional[str]) -> Optional[str]: + if not model_path: + return None + + config_path = Path(model_path) / "tokenizer_config.json" + if not config_path.exists(): + return None + + try: + tokenizer_config = json.loads(config_path.read_text(encoding="utf-8")) + except Exception: + return None + + chat_template = tokenizer_config.get("chat_template") + return chat_template if isinstance(chat_template, str) and chat_template.strip() else None + + def _render_native_chat_template(self, messages: List[Dict[str, str]], enable_thinking: bool) -> str: + if not self._qa_native_chat_template: + raise ValueError("native chat template unavailable") + + parts: List[str] = [] + if messages and messages[0].get("role") == "system": + parts.append("<|im_start|>system\n" + messages[0].get("content", "") + "<|im_end|>\n") + remaining = messages[1:] + else: + remaining = messages + + for message in remaining: + role = message.get("role", "") + content = message.get("content", "") + parts.append(f"<|im_start|>{role}\n{content}<|im_end|>\n") + + parts.append("<|im_start|>assistant\n") + if not enable_thinking: + parts.append("\n\n\n\n") + return "".join(parts) + + def _init_templates(self): + # QA 模板:保持原样,它是好的 + self.qa_template = Template("""<|im_start|>system +你是一个专业的医学专家。请基于【医疗文本】生成一个JSON格式的问答对。 +你必须只输出 JSON,不要输出额外解释,不要输出 或推理过程。 +输出要求(必须严格遵守): +1) 仅输出一个 JSON 对象,且字段仅有 question 与 answer; +2) 不得输出任何元话术(如“首先/用户/根据以上”)与思考内容; +3) answer 简明,控制在80字以内。 +<|im_end|> +<|im_start|>user +【医疗文本】:患者男,30岁,主诉牙痛3天。查体见右下阻生智齿。 +<|im_end|> +<|im_start|>assistant +{ + "question": "患者的主诉和查体结果提示什么问题?", + "answer": "患者主诉牙痛3天,查体发现右下阻生智齿,提示可能存在智齿冠周炎或牙髓炎。" +} +<|im_end|> +<|im_start|>user +【医疗文本】:女性,65岁。主诉:胸闷气短反复发作1年。查体及辅助检查:心电图ST段抬高。 +<|im_end|> +<|im_start|>assistant +{ + "question": "患者的主诉和查体结果提示什么问题?", + "answer": "胸闷气短伴ST段抬高,提示急性冠脉综合征风险,建议尽快心内科评估。" +} +<|im_end|> +<|im_start|>user +【医疗文本】:{{ context }} +<|im_end|> +<|im_start|>assistant +""") + + # 🟢 修正 CoT 模板:去除换行符,将示例写成紧凑的单行,避免 Python 字符串转义灾难 + self.cot_template = Template("""<|im_start|>system +你是一个资深的临床医生。请针对【医疗问题】生成JSON格式的思维链推理。 +逻辑路径:症状 -> 检查 -> 诊断 -> 治疗。 +你必须只输出 JSON,不要输出额外解释,不要输出 标签。 + 输出要求(必须严格遵守): + 1) 仅输出一个 JSON 对象,字段仅有 question/rationale/final_answer; + 2) rationale 使用条目化步骤表达(建议不少于6步); + 3) 禁止元话术与角色说明。 +<|im_end|> +<|im_start|>user +【医疗问题】:感冒引起的发热应该如何处理? +<|im_end|> +<|im_start|>assistant +{ + "question": "感冒引起的发热应该如何处理?", + "rationale": "1.症状分析:患者因感冒出现发热。2.辅助检查:必要时查血常规。3.初步判断:以上呼吸道感染为主。4.风险评估:关注高热与脱水。5.治疗策略:物理降温为主。6.用药原则:高热可口服解热镇痛药。", + "final_answer": "建议多休息、多饮水。若体温超过38.5℃,可服用退热药;否则采用物理降温。" +} +<|im_end|> +<|im_start|>user +【医疗问题】:男性,45岁。主诉:持续性干咳3天。查体及辅助检查:CT示斑片影。 +<|im_end|> +<|im_start|>assistant +{ + "question": "男性,45岁。主诉:持续性干咳3天。查体及辅助检查:CT示斑片影。", + "rationale": "1.症状提取:持续性干咳3天。2.关键检查:CT示斑片影。3.病因推断:以感染性肺部病变优先。4.鉴别方向:需与非感染性间质病变区分。5.进一步检查:血常规与炎症指标。6.处置建议:呼吸专科评估并随访影像。", + "final_answer": "当前首先考虑肺部炎症性病变,建议完善感染评估并尽快呼吸专科复诊。" +} +<|im_end|> +<|im_start|>user +【医疗问题】:{{ question }} +<|im_end|> +<|im_start|>assistant +""") + + # 偏好数据模板:生成 chosen/rejected 供偏好学习(含示例,减少叙述体输出) + self.preference_template = Template("""<|im_start|>system +你是医疗数据工程师。请基于【医疗问题】输出偏好学习样本(JSON)。 +要求: +1) chosen:高质量、准确且安全; +2) rejected:包含明显缺陷(如不完整、轻微逻辑问题或不够相关); +3) 输出字段必须为:question/chosen/rejected/preference_reason。 +你必须只输出 JSON,不要输出额外解释,不要输出 标签。 +chosen 与 rejected 均尽量简洁(建议各不超过80字)。 +preference_reason 必须具体说明“为什么 chosen 更好”,不得写空泛套话。 +<|im_end|> +<|im_start|>user +【医疗问题】:女性,65岁。主诉:胸闷气短反复发作1年。查体及辅助检查:心电图ST段抬高。 +<|im_end|> +<|im_start|>assistant +{ + "question": "女性,65岁。主诉:胸闷气短反复发作1年。查体及辅助检查:心电图ST段抬高。", + "chosen": "胸闷气短伴ST段抬高,优先考虑急性冠脉综合征,建议立即心电监护与心肌标志物复查。", + "rejected": "可能只是普通疲劳,先回家休息观察即可。", + "preference_reason": "chosen 结合了关键检查异常并给出及时处置;rejected 忽略高危心电图信号,存在安全风险。" +} +<|im_end|> +<|im_start|>user +【医疗问题】:{{ question }} +<|im_end|> +<|im_start|>assistant +""") + + self.task_templates = { + "QA": self.qa_template, + "CoT": self.cot_template, + "Preference": self.preference_template + } + + self.repair_templates = { + "QA": Template("""<|im_start|>system +你是JSON修复器。请把给定文本修复为合法JSON对象,且仅包含字段 question/answer。 +要求: +1) 只输出一个 JSON 对象; +2) 不要输出 、解释、markdown; +3) answer 控制在80字内。 +<|im_end|> +<|im_start|>user +【原始输入】:{{ source_text }} +【候选输出】:{{ raw_output }} +请修复为目标JSON。 +<|im_end|> +<|im_start|>assistant +"""), + "CoT": Template("""<|im_start|>system +你是JSON修复器。请把给定文本修复为合法JSON对象,且仅包含字段 question/rationale/final_answer。 +要求: +1) 只输出一个 JSON 对象; +2) rationale 使用步骤化表达(建议6步); +3) 不要输出 、解释、markdown。 +<|im_end|> +<|im_start|>user +【原始输入】:{{ source_text }} +【候选输出】:{{ raw_output }} +请修复为目标JSON。 +<|im_end|> +<|im_start|>assistant +"""), + "Preference": Template("""<|im_start|>system +你是JSON修复器。请把给定文本修复为合法JSON对象,且仅包含字段 question/chosen/rejected/preference_reason。 +要求: +1) 只输出一个 JSON 对象; +2) chosen 为更优回答,rejected 为较差回答,preference_reason 必须具体; +3) 不要输出 、解释、markdown。 +<|im_end|> +<|im_start|>user +【原始输入】:{{ source_text }} +【候选输出】:{{ raw_output }} +请修复为目标JSON。 +<|im_end|> +<|im_start|>assistant +"""), + } + + def _distill_text(self, text: str) -> str: + """轻量数据蒸馏:保留核心症状/检查信息,删除冗余语气词。""" + distilled = re.sub(r"(请问|可能|大概|有点|非常|真的)", "", text) + distilled = re.sub(r"\s+", "", distilled) + return f"[蒸馏]{distilled}" + + def _augment_text(self, text: str) -> List[str]: + """轻量数据增强:结构改写 + 关键信息重排。""" + variants = [ + f"患者信息:{text}", + f"病例摘要:{text}", + f"请根据以下临床片段生成训练数据:{text}", + f"【主诉与检查】{text}", + f"医学文本(需结构化):{text}" + ] + + # 若文本包含句号,尝试做结构重排增强 + parts = [p for p in re.split(r"[。;;]", text) if p.strip()] + if len(parts) >= 2: + reordered = ";".join(parts[1:] + parts[:1]) + "。" + variants.append(f"重排病历:{reordered}") + return variants + + def build_training_corpus( + self, + raw_inputs: List[str], + target_size: int, + source_ratio: Optional[Dict[str, float]] = None, + seed: int = 42 + ) -> List[Dict[str, str]]: + """ + 构建训练语料池,支持原始/增强/蒸馏数据配比。 + 返回格式: [{"source": "original|augmented|distilled", "text": "..."}, ...] + """ + if not raw_inputs: + return [] + + if source_ratio is None: + source_ratio = {"original": 0.4, "augmented": 0.4, "distilled": 0.2} + + ratio_sum = sum(source_ratio.values()) + if ratio_sum <= 0: + raise ValueError("source_ratio 总和必须 > 0") + + normalized_ratio = {k: v / ratio_sum for k, v in source_ratio.items()} + + random.seed(seed) + original_pool = list(raw_inputs) + augmented_pool = [aug for text in raw_inputs for aug in self._augment_text(text)] + distilled_pool = [self._distill_text(text) for text in raw_inputs] + + source_pools = { + "original": original_pool, + "augmented": augmented_pool, + "distilled": distilled_pool + } + + allocated = { + k: int(target_size * normalized_ratio.get(k, 0.0)) + for k in ["original", "augmented", "distilled"] + } + + remain = target_size - sum(allocated.values()) + for key in ["original", "augmented", "distilled"]: + if remain <= 0: + break + allocated[key] += 1 + remain -= 1 + + mixed = [] + for source_name, cnt in allocated.items(): + pool = source_pools[source_name] + if not pool: + continue + for i in range(cnt): + mixed.append({"source": source_name, "text": pool[i % len(pool)]}) + + random.shuffle(mixed) + return mixed + + def _clean_json_string(self, text: str) -> str: + text = text.strip() + + # 移除 Qwen 系列常见的思考段,避免污染 JSON + text = re.sub(r"[\s\S]*?", "", text, flags=re.IGNORECASE) + # 兼容未闭合 think 标签 + text = re.sub(r"[\s\S]*$", "", text, flags=re.IGNORECASE) + text = re.sub(r"<\|im_start\|>think[\s\S]*?<\|im_end\|>", "", text, flags=re.IGNORECASE) + + # 移除 Markdown 标记 + text = re.sub(r"^```json", "", text, flags=re.MULTILINE) + text = re.sub(r"^```", "", text, flags=re.MULTILINE) + text = text.strip() + + # 🟢 增强:处理模型输出真实换行符的情况 + # 将 JSON 值里的真实换行符替换为空格,防止 json.loads 失败 + # (这是一个简单的 trick,防止 "rationale": "第一行\n第二行" 报错) + # text = text.replace('\n', ' ') + # 上面这行太暴力,可能会破坏 JSON 结构,改用 strict=False 并在失败时尝试修复 + + extracted = self._extract_first_json_object(text) + return extracted if extracted else text + + def _repair_json_syntax_only(self, text: str) -> str: + """Only fix common JSON syntax issues; never invent missing content.""" + repaired = text.strip() + repaired = re.sub(r",(\s*[}\]])", r"\1", repaired) + repaired = repaired.replace(",}", "}").replace(",]", "]") + repaired = repaired.replace("“", '"').replace("”", '"') + return repaired + + def _extract_first_json_object(self, text: str) -> Optional[str]: + start = text.find("{") + if start == -1: + return None + + in_str = False + escaped = False + depth = 0 + for i in range(start, len(text)): + ch = text[i] + if in_str: + if escaped: + escaped = False + elif ch == "\\": + escaped = True + elif ch == '"': + in_str = False + continue + + if ch == '"': + in_str = True + elif ch == "{": + depth += 1 + elif ch == "}": + depth -= 1 + if depth == 0: + return text[start:i + 1] + + # 兜底:首个 { 到最后一个 } + last = text.rfind("}") + if last > start: + return text[start:last + 1] + return None + + def _strip_reasoning_text(self, text: str) -> str: + t = text.strip() + t = re.sub(r"[\s\S]*?", "", t, flags=re.IGNORECASE) + t = re.sub(r"[\s\S]*$", "", t, flags=re.IGNORECASE) + t = re.sub(r"<\|im_start\|>think[\s\S]*?<\|im_end\|>", "", t, flags=re.IGNORECASE) + t = re.sub(r"^```json", "", t, flags=re.MULTILINE) + t = re.sub(r"^```", "", t, flags=re.MULTILINE) + t = re.sub(r"\s+", " ", t).strip() + return t + + def _looks_like_meta_or_thought(self, text: str) -> bool: + if not text: + return True + lower = text.lower().strip() + for p in self.meta_phrases: + if p.lower() in lower: + return True + if lower.startswith("嗯") or lower.startswith("好的") or lower.startswith("首先"): + return True + return False + + def _check_length_limit(self, task_type: str, data: Dict[str, Any]) -> bool: + limits = self.length_limits.get(task_type, {}) + for k, max_len in limits.items(): + v = data.get(k) + if isinstance(v, str) and len(v.strip()) > max_len: + return False + return True + + def _passes_task_quality( + self, + task_type: str, + data: Dict[str, Any], + source_text: Optional[str] = None, + ) -> bool: + if not self._check_length_limit(task_type, data): + return False + + if source_text and self._has_obvious_source_contradiction(source_text, data): + return False + + if task_type == "QA": + q = str(data.get("question", "")).strip() + a = str(data.get("answer", "")).strip() + if self._looks_like_meta_or_thought(q) or self._looks_like_meta_or_thought(a): + return False + if len(a) < 8: + return False + return True + + if task_type == "CoT": + q = str(data.get("question", "")).strip() + r = str(data.get("rationale", "")).strip() + f = str(data.get("final_answer", "")).strip() + if ( + self._looks_like_meta_or_thought(q) + or self._looks_like_model_monologue(q) + or self._looks_like_meta_or_thought(r) + or self._looks_like_meta_or_thought(f) + ): + return False + # 简单步骤判定,避免输出成口语段落 + step_hits = len(re.findall(r"(\d+[\.、]|步骤\d+|->)", r)) + if step_hits < 3: + return False + return True + + if task_type == "Preference": + c = str(data.get("chosen", "")).strip() + rj = str(data.get("rejected", "")).strip() + pr = str(data.get("preference_reason", "")).strip() + if any(self._looks_like_meta_or_thought(x) or self._looks_like_model_monologue(x) for x in [c, rj, pr]): + return False + if c == rj: + return False + if pr in self.weak_preference_reasons: + return False + return True + + return True + + def _looks_like_model_monologue(self, text: str) -> bool: + value = (text or "").strip() + if not value: + return False + monologue_patterns = [ + r"我需要", + r"我会", + r"我首先", + r"让我", + r"这让我", + r"我认为", + r"我推测", + r"需要综合这些信息", + ] + return any(re.search(pattern, value) for pattern in monologue_patterns) + + def _contains_positive_recommendation(self, text: str, terms: List[str]) -> bool: + value = text or "" + for term in terms: + for match in re.finditer(re.escape(term), value): + prefix = value[max(0, match.start() - 12):match.start()] + if any(marker in prefix for marker in ["不", "无", "无需", "不需", "忽视", "拒绝", "暂不", "不能", "避免", "慎用", "除非", "仅在"]): + continue + return True + return False + + def _is_dka_source(self, source: str) -> bool: + return ( + ("血糖" in source) + and ("尿酮" in source or "酮体" in source) + and ("pH" in source or "HCO3" in source or "酸中毒" in source) + ) + + def _is_acute_stroke_source(self, source: str) -> bool: + return ( + ("突发" in source) + and ("肢体无力" in source or "言语不清" in source or "NIHSS" in source) + and ("CT未见出血" in source or ("CT" in source and "未见出血" in source)) + ) + + def _is_bacterial_pneumonia_source(self, source: str) -> bool: + return ( + ("发热" in source and ("咳嗽" in source or "气促" in source)) + and ("白细胞" in source or "中性粒细胞" in source or "CRP" in source) + and ("片状浸润" in source or "湿啰音" in source or "肺炎" in source) + ) + + def _has_unapproved_english_tokens(self, source_text: str, generated: str) -> bool: + if not generated: + return False + + if not re.search(r"[\u4e00-\u9fff]", source_text or ""): + return False + + forbidden = { + "insulin", "volume", + } + for token in re.findall(r"[A-Za-z][A-Za-z0-9+\-]*", generated): + normalized = token.lower().strip("+-") + if normalized in forbidden: + return True + return False + + def _has_obvious_source_contradiction(self, source_text: str, data: Dict[str, Any]) -> bool: + source = source_text or "" + generated = " ".join( + str(v) + for v in data.values() + if isinstance(v, (str, int, float)) + ) + if self._has_unapproved_english_tokens(source, generated): + return True + + def has_forbidden_without_negation(term: str) -> bool: + for m in re.finditer(re.escape(term), generated): + window = generated[max(0, m.start() - 48): m.end() + 40] + if any(marker in window for marker in ["排除", "不考虑", "不符合", "不适当", "不恰当", "无关", "否定", "不是", "不应", "不得", "禁止", "无需", "不需", "不常规", "非首选", "不作为", "避免", "慎用", "除非", "仅在", "不推荐"]): + continue + return True + return False + + if any(term in generated for term in ["preference 中", "Preference 中", "chosen 应", "rejected 应", "作为 chosen", "字段固定为", "既往规则", "根据规则", "prompt", "原始的诊断建议"]): + return True + if any(term in generated for term in ["曓", "�"]): + return True + if re.search(r"依据\d{2,}", generated): + return True + if re.search(r"\binsulin\b", generated, flags=re.IGNORECASE): + return True + + contradiction_pairs = [ + ("男", ["女性", "妇科", "卵巢", "黄体破裂", "子宫", "妊娠"]), + ("女", ["男性", "睾丸", "前列腺"]), + ] + for source_marker, forbidden_terms in contradiction_pairs: + if source_marker in source and any(has_forbidden_without_negation(term) for term in forbidden_terms): + return True + + if "腹股沟" in source and "阶梯状液气平" in source: + unrelated = ["睾丸扭转", "黄体破裂", "卵巢囊肿", "盆腔炎"] + final_answer = str(data.get("final_answer", "")) + chosen = str(data.get("chosen", "")) + if data.keys() >= {"chosen", "rejected", "preference_reason"}: + rejected = str(data.get("rejected", "")) + if any(term in rejected for term in unrelated): + return True + if any(term in chosen for term in unrelated): + return True + if not ("腹股沟疝" in chosen and "肠梗阻" in chosen): + return True + if any(has_forbidden_without_negation(term) for term in unrelated): + return True + if any(term in generated for term in ["穿孔", "引流", "推挤", "减压"]): + return True + if final_answer: + unsafe_delay = r"(延迟|延误|推迟|暂缓|暂不|不急).{0,12}(外科|手术|评估|处理)|观察并.{0,8}(延迟|延误|推迟|暂缓)" + for match in re.finditer(unsafe_delay, final_answer): + prefix = final_answer[max(0, match.start() - 6):match.start()] + if any(marker in prefix for marker in ["避免", "防止", "以免", "减少"]): + continue + return True + if "观察" in final_answer and not any(term in final_answer for term in ["外科评估", "急诊", "手术", "尽快", "及时"]): + return True + + if "食管裂孔疝" in source: + chosen = str(data.get("chosen", "")) + rejected = str(data.get("rejected", "")) + if ( + self._contains_positive_recommendation(rejected, ["手术治疗", "手术评估", "外科评估"]) + and not any(term in chosen for term in ["食管裂孔疝", "裂孔疝", "手术", "外科评估"]) + ): + return True + + if all(term in source for term in ["II", "III", "aVF", "ST段抬高"]): + if any(term in generated for term in ["左心上室", "前壁心肌梗死", "高侧壁心肌梗死", "冠状动脉栓塞", "心尖端", "非心尖"]): + return True + if any(term in generated for term in ["心脏起搏器检查", "心包反射", "心包疾病"]): + return True + if re.search(r"排除.{0,10}心肌梗死|心肌梗死.{0,10}排除", generated): + return True + + if self._is_dka_source(source): + chosen = str(data.get("chosen", "")) + rejected = str(data.get("rejected", "")) + final_answer = str(data.get("final_answer", "")) + if re.search(r"HCO3-?.{0,8}(增高|升高|增加|偏高)", generated, flags=re.IGNORECASE): + return True + if any(term in generated for term in ["抗激素", "神经系统受损原因", "神经系统损伤", "神经系统受损"]): + return True + if "高血压" not in source and any(term in generated for term in ["原发性高血压", "高血压病"]): + return True + if not any(term in generated for term in ["糖尿病酮症酸中毒", "酮症酸中毒", "DKA"]): + return True + if has_forbidden_without_negation("碳酸氢钠") and "pH 6.9" not in source and "pH<6.9" not in source: + return True + if data.keys() >= {"chosen", "rejected", "preference_reason"}: + if not any(term in chosen for term in ["胰岛素", "补液", "液体复苏"]): + return True + if ( + self._contains_positive_recommendation(chosen, ["碳酸氢钠", "抗生素"]) + and self._contains_positive_recommendation(rejected, ["胰岛素", "补液", "液体复苏"]) + ): + return True + if final_answer and not any(term in final_answer for term in ["胰岛素", "补液", "液体复苏"]): + return True + + if self._is_acute_stroke_source(source): + if "缺抗性卒中" in generated: + return True + if any(term in generated for term in ["脑干梗死", "血管痉挛", "阿瑟曼征", "侧枝循环障碍"]): + return True + if has_forbidden_without_negation("SPECT"): + return True + if data.keys() >= {"chosen", "rejected", "preference_reason"}: + rejected = str(data.get("rejected", "")) + if self._contains_positive_recommendation(rejected, ["机械取栓", "取栓", "再灌注"]): + return True + if re.search(r"(先行|优先|先做|先完善).{0,12}(MRI|磁共振).{0,18}(再|后).{0,8}(溶栓|取栓|再灌注)", generated): + return True + if re.search(r"(延后|延迟|暂缓|推迟).{0,10}(溶栓|取栓|再灌注)", generated): + return True + if "CT未见出血" in source and "溶栓" in generated and re.search(r"(不应|不能|无需|不推荐).{0,8}溶栓", generated): + return True + + if self._is_bacterial_pneumonia_source(source): + chosen = str(data.get("chosen", "")) + rejected = str(data.get("rejected", "")) + if any(term in generated for term in ["腹股沟疝", "肠梗阻", "腹股沟包块"]): + return True + if "CRP升高" in source and any(term in generated for term in ["正常CRP", "CRP正常", "CRP不高", "CRP未升高"]): + return True + if any(term in generated for term in ["无呼吸道症状", "无细菌证据", "没有细菌感染证据", "缺乏细菌感染证据"]): + return True + if has_forbidden_without_negation("病毒感染"): + return True + if data.keys() >= {"chosen", "rejected", "preference_reason"}: + chosen_antiviral = self._contains_positive_recommendation(chosen, ["抗病毒"]) + rejected_antibiotic = self._contains_positive_recommendation(rejected, ["抗生素", "抗感染"]) + if chosen_antiviral and rejected_antibiotic: + return True + if not any(term in chosen for term in ["抗生素", "抗感染", "细菌性肺炎"]): + return True + + return False + + def _build_source_guardrail(self, source_text: str, task_type: Optional[str] = None) -> str: + source = source_text or "" + rules: List[str] = [] + if "男" in source: + rules.append("病例为男性。") + if "女" in source: + rules.append("病例为女性。") + if "腹股沟" in source and "包块" in source: + rules.append("腹股沟包块合并阶梯状液气平时,应围绕嵌顿性腹股沟疝合并肠梗阻分析。") + rules.append("所有字段禁止出现穿孔、引流、推挤、减压等原文未给出的并发症或处置。") + rules.append("CoT 任务中,final_answer 必须建议尽快外科或急诊外科评估,不得建议观察、延迟外科评估或延迟手术。") + rules.append("Preference 任务中,chosen 必须字面包含:嵌顿性腹股沟疝合并肠梗阻,并建议尽快外科评估;不得把卵巢囊肿、盆腔炎、睾丸扭转、阑尾肿瘤等作为 chosen。") + rules.append("Preference 任务中,rejected 不得是疾病名,严禁输出卵巢囊肿、盆腔炎、睾丸扭转等其他诊断名称;必须用同一病例的低质量处理建议作为 rejected,例如仅建议观察、延误外科评估、忽视肠梗阻证据或未及时处理嵌顿疝。") + if "食管裂孔疝" in source: + rules.append("食管裂孔疝病例应同时覆盖反流性食管炎、食管裂孔疝和反流相关咳喘。") + rules.append("Preference 任务中,chosen 应是更完整答案;不得把手术治疗、手术评估或外科评估作为 rejected 的优点。") + if all(term in source for term in ["II", "III", "aVF", "ST段抬高"]): + rules.append("II、III、aVF导联ST段抬高合并肌钙蛋白升高时,应明确为急性下壁STEMI或下壁心肌梗死。") + rules.append("处理建议应聚焦急诊心内科评估、抗栓治疗、冠脉造影评估和再灌注策略。") + if self._is_dka_source(source): + rules.append("血糖显著升高、尿酮体阳性、pH/HCO3-提示酸中毒时,应围绕糖尿病酮症酸中毒分析。") + rules.append("处理原则必须包括补液或液体复苏、静脉胰岛素、钾/电解质监测与纠正,并寻找诱因。") + if task_type == "Preference": + rules.append("Preference 的 chosen 必须同时包含诊断和处理:糖尿病酮症酸中毒、补液、静脉胰岛素、电解质监测纠正;rejected 应写同病例低质量处置,例如仅观察或只控制血糖而遗漏补液和电解质管理。") + rules.append("治疗表述只使用中文胰岛素,不使用英文 insulin;不要输出编号残片。") + rules.append("只输出上述诊断依据和处理原则,不扩展原文未提供的其他系统病因或常规外治疗。") + if self._is_acute_stroke_source(source): + rules.append("突发偏瘫/言语不清且头颅CT未见出血时,应按急性缺血性卒中路径分析。") + rules.append("处置应包括卒中中心评估、静脉溶栓时间窗/禁忌评估、必要时机械取栓评估、血压和血糖管理。") + rules.append("不得无依据写脑干梗死、血管痉挛或SPECT;不得要求先做MRI/SPECT而延误溶栓或再灌注评估。") + if task_type == "Preference": + rules.append("Preference 中 chosen 不得写既往规则、根据规则或 prompt 话术;rejected 不得否定机械取栓或再灌注评估,应写同病例低质量回答,例如仅观察、延误溶栓、忽视CT未见出血或忽视时间窗。") + if self._is_bacterial_pneumonia_source(source): + rules.append("儿童发热咳嗽、湿啰音、白细胞/中性粒细胞/CRP升高和片状浸润影时,应优先围绕细菌性肺炎分析。") + if task_type == "Preference": + rules.append("Preference 中 chosen 应支持经验性抗生素或抗感染治疗及支持治疗;不得把抗病毒优先方案作为 chosen。") + rules.append("Preference 中 rejected 必须是同病例低质量回答,例如仅抗病毒、仅观察、延误抗生素或忽视细菌感染证据;不得写不适用、信息不足、妇科疾病或其他无关内容。") + rules.append("Preference 的 rejected 不得写无呼吸道症状,不得写无细菌证据,不得写缺乏细菌感染证据;因为原始病例已经有发热咳嗽、白细胞/CRP升高和片状浸润影。") + if rules: + rules.append("以上规则只用于约束生成,禁止把规则原句、字段名或 prompt 要求写入输出内容。") + return " ".join(rules) + + def _render_prompt(self, task_type: str, text: str) -> str: + if task_type not in self.task_templates: + raise ValueError(f"不支持的 task_type: {task_type}") + + if task_type == "QA": + return self._render_qa_fast_prompt(text) + if task_type == "CoT": + return self._render_cot_native_prompt(text) + if task_type == "Preference": + return self._render_preference_native_prompt(text) + raise ValueError(f"不支持的 task_type: {task_type}") + + def _render_qa_fast_prompt(self, text: str) -> str: + compact = text.strip() + guardrail = self._build_source_guardrail(compact, "QA") + if self._qa_uses_native_template: + messages = [ + { + "role": "system", + "content": ( + "Generate one medical QA JSON object from the source text. " + "Output JSON only. Do not output explanations or . " + "Use exactly two fields: question and answer. " + "Keep answer concise and grounded in the source text. " + f"{guardrail}" + ), + }, + { + "role": "user", + "content": compact, + }, + ] + return self._render_native_chat_template(messages, enable_thinking=False) + + return ( + "<|im_start|>system\n" + "Generate one medical QA JSON object from the source text. " + "Output JSON only. Do not output explanations or . " + "Use exactly two fields: question and answer. " + "Keep answer concise and grounded in the source text. " + f"{guardrail}\n" + "<|im_end|>\n" + "<|im_start|>user\n" + f"{compact}\n" + "<|im_end|>\n" + "<|im_start|>assistant\n" + "\n\n\n\n" + ) + + def _render_cot_native_prompt(self, text: str) -> str: + compact = text.strip() + guardrail = self._build_source_guardrail(compact, "CoT") + if self._qa_uses_native_template: + messages = [ + { + "role": "system", + "content": ( + "你是资深临床医生。请基于用户给出的中文病例生成一个 CoT JSON 对象。" + "只能输出 JSON,不要输出解释或 。" + "字段固定为 question、rationale、final_answer。" + "question 必须是一个简短的临床问题,不得写模型自述、推理过程、'我需要'或'这让我'。" + "rationale 必须是一个中文字符串,不要使用数组;必须包含六个编号:1. 2. 3. 4. 5. 6.。" + "每个编号步骤必须引用输入病例中的症状、检查或处置依据,每步尽量不超过35字。" + "final_answer 必须与病例一致,不得引入输入中不存在的症状或检查。" + f"{guardrail}" + ), + }, + {"role": "user", "content": compact}, + ] + return self._render_native_chat_template(messages, enable_thinking=False) + return self.cot_template.render(question=text) + + def _render_preference_native_prompt(self, text: str) -> str: + compact = text.strip() + guardrail = self._build_source_guardrail(compact, "Preference") + if self._qa_uses_native_template: + messages = [ + { + "role": "system", + "content": ( + "你是医疗数据工程师。请基于用户给出的中文病例生成一个偏好学习 JSON 对象。" + "只能输出 JSON,不要输出解释或 。" + "字段固定为 question、chosen、rejected、preference_reason。" + "chosen 必须是准确、安全、完整的医学回答。" + "rejected 必须是明显较差但与同一病例相关的回答,不得写成无关疾病。" + "rejected 应写成同一病例下的错误处置、遗漏关键证据或不安全建议,不要列举与病例性别/部位冲突的其他疾病。" + "每个字段保持简短,避免长篇背景解释。" + "如果病例为男性,禁止输出妇科疾病;如果病例为女性,禁止输出男性生殖系统疾病。" + f"{guardrail}" + "preference_reason 必须具体比较 chosen 为什么更好。" + ), + }, + {"role": "user", "content": compact}, + ] + return self._render_native_chat_template(messages, enable_thinking=False) + return self.preference_template.render(question=text) + + def _render_repair_prompt( + self, + task_type: str, + source_text: str, + raw_output: str, + repair_note: Optional[str] = None, + ) -> str: + if task_type not in self.repair_templates: + raise ValueError(f"不支持的 task_type: {task_type}") + # 限制候选输出长度,避免修复阶段 prompt 过长 + clipped = (raw_output or "")[:2400] + note = f"\n质量校验失败原因:{repair_note}" if repair_note else "" + if self._qa_uses_native_template: + fields = "/".join(self.required_fields.get(task_type, [])) + guardrail = self._build_source_guardrail(source_text, task_type) + groin_repair_rules = "" + if "腹股沟" in (source_text or "") and "阶梯状液气平" in (source_text or ""): + groin_repair_rules = ( + "腹股沟包块合并阶梯状液气平时,chosen 必须写嵌顿性腹股沟疝合并肠梗阻并建议尽快外科评估。" + "腹股沟包块合并阶梯状液气平的 Preference 修复中,chosen 必须字面包含:嵌顿性腹股沟疝合并肠梗阻;rejected 不得是疾病名,只能写同一病例下的低质量处置。" + "腹股沟包块合并阶梯状液气平时,所有字段禁止出现穿孔、引流、推挤、减压等原文未给出的并发症或处置。" + "腹股沟包块合并肠梗阻风险时,CoT 的 final_answer 不得建议观察、延迟外科评估或延迟手术。" + ) + messages = [ + { + "role": "system", + "content": ( + f"你是严格的 JSON 修复器。只输出一个合法 JSON 对象,字段固定为 {fields}。" + "不要输出解释、markdown 或 。" + "只能基于原始输入和候选输出修复结构,不得编造原文不存在的诊断、症状或检查。" + "CoT 的 rationale 必须写成单个编号字符串,不得使用数组;必须包含六个编号:1. 2. 3. 4. 5. 6.;final_answer 必须存在且简短。" + "Preference 的 rejected 必须是同一病例下的低质量回答,不得用与病例性别或部位冲突的其他疾病凑数。" + "如果 Preference 候选 rejected 是离题疾病或其他诊断名称,必须改写为同病例低质量处置建议,例如仅建议观察、延误外科评估、忽视关键检查或遗漏高危证据。" + "如果 Preference 候选 chosen 是离题疾病或其他错误诊断,必须改写为原始输入支持的正确答案。" + f"{groin_repair_rules}" + "CoT 的 final_answer 必须是安全处置建议,不得输出明显错误的首要处理。" + f"{guardrail}" + ), + }, + { + "role": "user", + "content": ( + f"原始输入:{source_text}\n" + f"候选输出:{clipped}\n" + f"{note}\n" + "请修复为目标 JSON。" + ), + }, + ] + return self._render_native_chat_template(messages, enable_thinking=False) + return self.repair_templates[task_type].render(source_text=source_text, raw_output=clipped) + + def _build_repair_retry_note(self, task_type: str, source_text: str, raw_output: str) -> str: + source = source_text or "" + notes: List[str] = ["上一轮输出仍未通过质量校验,必须重写为合格 JSON。"] + if "腹股沟" in source and "阶梯状液气平" in source: + notes.append("删除所有字段中的禁用并发症或处置词,不要复述上一轮中的禁用表述。") + notes.append("CoT final_answer 只保留嵌顿性腹股沟疝合并肠梗阻和尽快外科评估。") + notes.append("Preference chosen 必须包含嵌顿性腹股沟疝合并肠梗阻,rejected 只能是同病例低质量处置。") + if raw_output: + notes.append("不要保留候选输出中触发上述问题的表达。") + return " ".join(notes) + + def _sanitize_failed_repair_output(self, source_text: str, raw_output: str) -> str: + sanitized = raw_output or "" + if "腹股沟" in (source_text or "") and "阶梯状液气平" in (source_text or ""): + sanitized = re.sub(r"避免延误导致[^。;;,,\"]+", "避免延误处理", sanitized) + sanitized = re.sub(r"防止[^。;;,,\"]+", "避免延误处理", sanitized) + sanitized = re.sub(r"(穿孔|肠穿孔|引流|推挤|减压)", "", sanitized) + if self._is_dka_source(source_text or ""): + sanitized = re.sub(r"(抗激素|神经系统受损原因|神经系统损伤|神经系统受损|碳酸氢钠|抗生素)", "", sanitized) + sanitized = re.sub(r"\binsulin\b", "", sanitized, flags=re.IGNORECASE) + sanitized = re.sub(r"依据\d+", "", sanitized) + if self._is_bacterial_pneumonia_source(source_text or ""): + sanitized = sanitized.replace("无呼吸道症状或无细菌证据", "忽视已有细菌感染证据") + sanitized = sanitized.replace("无呼吸道症状", "有呼吸道症状") + sanitized = sanitized.replace("无细菌证据", "忽视已有细菌感染证据") + sanitized = sanitized.replace("缺乏细菌感染证据", "忽视已有细菌感染证据") + return sanitized[:1800] + + def _render_second_repair_prompt(self, task_type: str, source_text: str, raw_output: str) -> str: + sanitized = self._sanitize_failed_repair_output(source_text, raw_output) + if self._qa_uses_native_template: + fields = "/".join(self.required_fields.get(task_type, [])) + guardrail = self._build_source_guardrail(source_text, task_type) + source = source_text or "" + groin_instruction = "" + if "腹股沟" in source and "阶梯状液气平" in source: + groin_instruction = "腹股沟包块合并阶梯状液气平时,诊断和处置只写:嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。" + content = ( + f"你是严格的 JSON 二次修复器。只输出一个合法 JSON 对象,字段固定为 {fields}。" + "请完全重写,不要沿用上一轮原句,不要输出解释、markdown 或 。" + "必须只根据原始输入和允许的医学结论生成,不能扩展原文未给出的并发症或处置。" + "CoT 的 rationale 必须写成单个编号字符串,不得使用数组;必须包含六个编号:1. 2. 3. 4. 5. 6.;final_answer 必须存在。" + f"{groin_instruction}" + f"{guardrail}" + ) + if task_type == "CoT": + user_content = ( + f"原始输入:{source_text}\n" + "上一轮候选输出结构不合格,已丢弃。请只基于原始输入重新生成目标 JSON。" + ) + else: + user_content = ( + f"原始输入:{source_text}\n" + f"上一轮失败输出(已清理禁用词):{sanitized}\n" + "请重新生成目标 JSON。" + ) + messages = [ + {"role": "system", "content": content}, + {"role": "user", "content": user_content}, + ] + return self._render_native_chat_template(messages, enable_thinking=False) + return self._render_repair_prompt(task_type, source_text, sanitized, self._build_repair_retry_note(task_type, source_text, sanitized)) + + def _normalize_parsed_data(self, task_type: str, data: Any) -> Optional[Dict[str, Any]]: + if not isinstance(data, dict): + return None + + allowed = self.required_fields.get(task_type, []) + if task_type == "QA" and "answer" not in data: + for alias in ["处理原则", "诊断", "结论", "回答", "answer_text"]: + if alias in data: + data = dict(data) + data["answer"] = data.get(alias) + break + normalized = {key: data.get(key) for key in allowed} + + if task_type == "CoT" and isinstance(normalized.get("rationale"), list): + normalized["rationale"] = "".join( + f"{i + 1}. {str(step).strip()}" + for i, step in enumerate(normalized["rationale"]) + if str(step).strip() + ) + elif task_type == "CoT" and isinstance(normalized.get("rationale"), str): + normalized["rationale"] = self._normalize_cot_rationale_text(normalized["rationale"]) + + return normalized + + def _normalize_cot_rationale_text(self, rationale: str) -> str: + text = re.sub(r"\s+", " ", rationale or "").strip() + if not text: + return text + if len(re.findall(r"(\d+[\.、]|步骤\d+|->)", text)) >= 3: + return text + + parts = [p.strip(" ;;。") for p in re.split(r"[。;;]", text) if p.strip(" ;;。")] + if len(parts) < 3: + comma_parts = [p.strip(" ,,") for p in re.split(r"[,,]", text) if p.strip(" ,,")] + if len(comma_parts) >= 4: + parts = comma_parts + + if len(parts) < 3: + return text + + steps = parts[:6] + return "".join(f"{i + 1}. {step}。" for i, step in enumerate(steps)) + + def _validate_generated_data( + self, + task_type: str, + data: Dict[str, Any], + source_text: Optional[str] = None, + ) -> bool: + required = self.required_fields.get(task_type, []) + if not required: + return False + if set(data.keys()) != set(required): + return False + for key in required: + value = data.get(key) + if value is None: + return False + if isinstance(value, str) and not value.strip(): + return False + return self._passes_task_quality(task_type, data, source_text) + + def _build_sampling_params(self, task_type: str) -> SamplingParams: + # 延迟优化策略:QA/Preference 限长提速;CoT 放宽长度获取更详细推理 + if task_type == "QA": + return SamplingParams( + temperature=0.0, + top_p=0.8, + max_tokens=220, + stop=["<|im_end|>"], + repetition_penalty=1.0, + ) + + if task_type == "Preference": + return SamplingParams( + temperature=0.0, + top_p=1.0, + max_tokens=320, + stop=["<|im_end|>"], + repetition_penalty=1.03, + structured_outputs=self._structured_json_params("Preference"), + ) + + # CoT:不刻意限短,保留较大 token 预算生成更长推理 + return SamplingParams( + temperature=0.0, + top_p=1.0, + max_tokens=900, + stop=["<|im_end|>"], + repetition_penalty=1.05, + structured_outputs=self._structured_json_params("CoT"), + ) + + def _build_repair_sampling_params(self, task_type: str) -> SamplingParams: + # 修复阶段使用更低随机性,优先稳定产出结构化 JSON + if task_type == "QA": + max_tokens = 220 + elif task_type == "CoT": + max_tokens = 1400 + else: + max_tokens = 360 + + return SamplingParams( + temperature=0.0, + top_p=0.9, + max_tokens=max_tokens, + stop=["<|im_end|>"], + repetition_penalty=1.0, + structured_outputs=self._structured_json_params(task_type) if task_type in ["CoT", "Preference"] else None, + ) + + def _structured_json_params(self, task_type: str) -> Any: + schema = self._json_schema_for_task(task_type) + if StructuredOutputsParams is not None: + return StructuredOutputsParams(json=schema, disable_any_whitespace=True) + return {"json": schema, "disable_any_whitespace": True} + + def _json_schema_for_task(self, task_type: str) -> Dict[str, Any]: + if task_type == "CoT": + return { + "type": "object", + "additionalProperties": False, + "required": ["question", "rationale", "final_answer"], + "properties": { + "question": {"type": "string", "minLength": 4, "maxLength": 220}, + "rationale": { + "type": "string", + "minLength": 40, + "maxLength": 900, + }, + "final_answer": {"type": "string", "minLength": 8, "maxLength": 220}, + }, + } + if task_type == "Preference": + return { + "type": "object", + "additionalProperties": False, + "required": ["question", "chosen", "rejected", "preference_reason"], + "properties": { + "question": {"type": "string", "minLength": 4, "maxLength": 220}, + "chosen": {"type": "string", "minLength": 8, "maxLength": 180}, + "rejected": {"type": "string", "minLength": 8, "maxLength": 180}, + "preference_reason": {"type": "string", "minLength": 12, "maxLength": 220}, + }, + } + raise ValueError(f"不支持的 task_type: {task_type}") + + def _truncate_text_at_boundary(self, text: str, limit: int) -> str: + value = text.strip() + if len(value) <= limit: + return value + + cut = value[:limit].rstrip() + + sentence_marks = "。!?.!?" + last_sentence = max(cut.rfind(mark) for mark in sentence_marks) + if last_sentence >= 20: + return cut[:last_sentence + 1].rstrip() + + phrase_marks = ";;,,、::" + last_phrase = max(cut.rfind(mark) for mark in phrase_marks) + if last_phrase >= 20: + return cut[:last_phrase].rstrip() + + last_space = cut.rfind(" ") + if last_space >= 20: + return cut[:last_space].rstrip(" ,;:") + + return cut.rstrip() + + def _truncate_qa_fields(self, data: Dict[str, Any]) -> Dict[str, Any]: + normalized = dict(data) + question = str(normalized.get("question", "")).strip() + answer = str(normalized.get("answer", "")).strip() + + q_limit = self.length_limits["QA"]["question"] + a_limit = self.length_limits["QA"]["answer"] + + normalized["question"] = self._truncate_text_at_boundary(question, q_limit) + normalized["answer"] = self._truncate_text_at_boundary(answer, a_limit) + + return normalized + + def _try_parse_and_validate( + self, + task_type: str, + text: str, + source_text: Optional[str] = None, + ) -> Optional[Dict[str, Any]]: + clean_text = self._clean_json_string(text) + candidates = [ + clean_text, + self._repair_json_syntax_only(clean_text), + clean_text.replace('\n', '\\n'), + self._repair_json_syntax_only(clean_text).replace('\n', '\\n'), + ] + + for candidate in candidates: + try: + data = json.loads(candidate, strict=False) + data = self._normalize_parsed_data(task_type, data) + if data is None: + continue + if task_type == "QA": + data = self._truncate_qa_fields(data) + if self._validate_generated_data(task_type, data, source_text): + return data + except Exception: + continue + return None + + def _repair_failed_batch(self, task_type: str, repair_items: List[Dict[str, Any]]) -> Dict[int, Dict[str, Any]]: + """ + 对首轮失败样本执行二阶段修复。 + repair_items: [{"idx": int, "source_text": str, "raw_output": str}, ...] + 返回: {idx: {"status": ..., "data": ...}} + """ + if not repair_items: + return {} + + prompts = [ + self._render_repair_prompt(task_type, item["source_text"], item.get("raw_output", "")) + for item in repair_items + ] + repair_outputs = self.llm.generate(prompts, self._build_repair_sampling_params(task_type)) + + repaired_result_map: Dict[int, Dict[str, Any]] = {} + retry_items: List[Dict[str, Any]] = [] + for item, output in zip(repair_items, repair_outputs): + idx = item["idx"] + repaired_text = output.outputs[0].text if output.outputs else "" + parsed = self._try_parse_and_validate(task_type, repaired_text, item["source_text"]) + if parsed is not None: + repaired_result_map[idx] = { + "status": "success", + "data": parsed, + "repaired": True, + } + continue + + retry_items.append({ + "idx": idx, + "source_text": item["source_text"], + "raw_output": item.get("raw_output", ""), + "repair_raw_output": repaired_text, + }) + + if retry_items: + retry_prompts = [ + self._render_second_repair_prompt(task_type, item["source_text"], item.get("repair_raw_output", "")) + for item in retry_items + ] + retry_outputs = self.llm.generate(retry_prompts, self._build_repair_sampling_params(task_type)) + + for item, output in zip(retry_items, retry_outputs): + idx = item["idx"] + retry_text = output.outputs[0].text if output.outputs else "" + parsed = self._try_parse_and_validate(task_type, retry_text, item["source_text"]) + if parsed is not None: + repaired_result_map[idx] = { + "status": "success", + "data": parsed, + "repaired": True, + "repair_attempts": 2, + } + continue + + repaired_result_map[idx] = { + "status": "failed", + "reason": "repair_failed", + "raw_output": item.get("raw_output", ""), + "repair_raw_output": item.get("repair_raw_output", ""), + "second_repair_raw_output": retry_text, + } + + for item in retry_items: + idx = item["idx"] + if idx in repaired_result_map: + continue + repaired_result_map[idx] = { + "status": "failed", + "reason": "repair_failed", + "raw_output": item.get("raw_output", ""), + "repair_raw_output": item.get("repair_raw_output", ""), + } + + return repaired_result_map + + def generate_data_batch(self, task_type: str, inputs: List[str]) -> List[Dict[str, Any]]: + if task_type not in self.task_templates: + raise ValueError(f"不支持的 task_type: {task_type}") + + prompts = [] + for text in inputs: + prompts.append(self._render_prompt(task_type, text)) + + sampling_params = self._build_sampling_params(task_type) + + outputs = self.llm.generate(prompts, sampling_params) + + # 先占位,首轮失败的样本进入二阶段修复 + results: List[Optional[Dict[str, Any]]] = [None] * len(outputs) + repair_items: List[Dict[str, Any]] = [] + + for i, output in enumerate(outputs): + generated_text = output.outputs[0].text if output.outputs else "" + parsed = self._try_parse_and_validate(task_type, generated_text, inputs[i]) + if parsed is not None: + results[i] = {"status": "success", "data": parsed} + continue + + # 首轮直接失败,进入修复阶段 + repair_items.append({ + "idx": i, + "source_text": inputs[i], + "raw_output": generated_text, + }) + + repaired_map = self._repair_failed_batch(task_type, repair_items) + for item in repair_items: + idx = item["idx"] + if idx in repaired_map: + results[idx] = repaired_map[idx] + else: + results[idx] = { + "status": "failed", + "reason": "repair_missing", + "raw_output": item.get("raw_output", ""), + } + + # 理论上不应存在 None,这里兜底 + for i, r in enumerate(results): + if r is None: + results[i] = { + "status": "failed", + "reason": "internal_empty_result", + "raw_output": "", + } + + + return [r for r in results if r is not None] + + def _extract_case_parts(self, source_text: str) -> Dict[str, str]: + demo = "" + symptom = "" + finding = "" + + m_demo = re.search(r"^(.*?)。主诉[::]", source_text) + if m_demo: + demo = m_demo.group(1).strip() + + m_symptom = re.search(r"主诉[::](.*?)。查体", source_text) + if m_symptom: + symptom = m_symptom.group(1).strip() + + m_finding = re.search(r"查体及辅助检查[::](.*?)(。|$)", source_text) + if m_finding: + finding = m_finding.group(1).strip() + + if not demo and not symptom and not finding: + return { + "demo": "患者", + "symptom": source_text.strip()[:60], + "finding": "检查信息待补充", + } + + return { + "demo": demo or "患者", + "symptom": symptom or "症状待补充", + "finding": finding or "检查信息待补充", + } + + def _infer_primary_assessment(self, finding: str) -> str: + f = finding or "" + if "ST段抬高" in f: + return "急性冠脉综合征风险" + if "脑梗死" in f: + return "脑梗死相关神经功能受损" + if "斑片影" in f: + return "肺部炎症性病变" + if "结石" in f: + return "结石相关器官病变" + if "尿蛋白" in f: + return "肾脏受损风险" + if "白细胞升高" in f or "CRP升高" in f: + return "感染或炎症反应" + return "临床异常需进一步评估" + +if __name__ == "__main__": + pass diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/requirement_metrics.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/requirement_metrics.py new file mode 100644 index 00000000..11922e1e --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/requirement_metrics.py @@ -0,0 +1,83 @@ +from __future__ import annotations + +from typing import Dict, List, Any, Iterable + + +REQUIRED_FIELDS = { + "QA": ["question", "answer"], + "CoT": ["question", "rationale", "final_answer"], + "Preference": ["question", "chosen", "rejected", "preference_reason"], +} + + +def _safe_mean(values: Iterable[float]) -> float: + values = list(values) + return sum(values) / len(values) if values else 0.0 + + +def _field_complete(item: Dict[str, Any], task_type: str) -> bool: + required = REQUIRED_FIELDS.get(task_type, []) + for key in required: + v = item.get(key) + if v is None: + return False + if isinstance(v, str) and not v.strip(): + return False + return True + + +def calculate_generation_metrics( + records: List[Dict[str, Any]], + evaluator_scores: List[Dict[str, Any]], +) -> Dict[str, float]: + """ + records: [{task_type, status, latency, data:{...}}] + evaluator_scores: [{scores:{维度:{score:int}}}] + """ + avg_latency = _safe_mean(r.get("latency", 0.0) for r in records) + + format_integrity = _safe_mean( + 1.0 if (r.get("status") == "success" and _field_complete(r.get("data", {}), r.get("task_type", ""))) else 0.0 + for r in records + ) * 100 + + # 多样性口径:成功样本中的唯一 question 数 + questions = [ + r.get("data", {}).get("question", "").strip() + for r in records + if r.get("status") == "success" + ] + diversity_count = len({q for q in questions if q}) + + def dim_rate(dim: str) -> float: + valid = [] + for item in evaluator_scores: + score = item.get("scores", {}).get(dim, {}).get("score", -1) + if isinstance(score, int) and score >= 0: + valid.append(1.0 if score == 1 else 0.0) + return _safe_mean(valid) * 100 + + metrics = { + "avg_latency_sec": avg_latency, + "format_integrity_pct": format_integrity, + "accuracy_pct": dim_rate("准确性"), + "relevance_pct": dim_rate("相关性"), + "safety_pct": dim_rate("安全性"), + "diversity_pct": dim_rate("多样性"), + "completeness_pct": dim_rate("完整性"), + "diversity_count": float(diversity_count), + } + return metrics + + +def check_project_targets(metrics: Dict[str, float]) -> Dict[str, bool]: + """按需求阈值判断是否达标。""" + return { + "latency_ok": metrics.get("avg_latency_sec", 999) <= 3.0, + "accuracy_ok": metrics.get("accuracy_pct", 0) >= 90.0, + "relevance_ok": metrics.get("relevance_pct", 0) >= 95.0, + "safety_ok": metrics.get("safety_pct", 0) >= 95.0, + "diversity_ok": metrics.get("diversity_pct", 0) >= 85.0, + "completeness_ok": metrics.get("completeness_pct", 0) >= 85.0, + "format_integrity_ok": metrics.get("format_integrity_pct", 0) >= 100.0, + } diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/test_evaluator_backend.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/test_evaluator_backend.py new file mode 100644 index 00000000..02e47c91 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/test_evaluator_backend.py @@ -0,0 +1,110 @@ +import json +import os +import sys +import unittest + + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +if CURRENT_DIR not in sys.path: + sys.path.insert(0, CURRENT_DIR) + +from data_evaluator import MedicalDataEvaluator + + +class _FakeCandidate: + def __init__(self, text): + self.text = text + + +class _FakeResult: + def __init__(self, text): + self.outputs = [_FakeCandidate(text)] + + +class EvaluatorBackendTests(unittest.TestCase): + def test_vllm_backend_calls_llm_generate(self): + class CountingLLM: + def __init__(self): + self.calls = 0 + self.prompt_count = 0 + self.prompts = [] + + def generate(self, prompts, sampling_params): + self.calls += 1 + self.prompt_count += len(prompts) + self.prompts.extend(prompts) + return [ + _FakeResult(json.dumps({"score": 1, "reason": "model judged pass"})) + for _ in prompts + ] + + llm = CountingLLM() + evaluator = MedicalDataEvaluator( + model_path=None, + llm_instance=llm, + backend="vllm", + ) + dimension = next(iter(evaluator.dimension_criteria)) + + results = evaluator.evaluate( + [{"id": 1, "type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}], + target_dimensions=[dimension], + ) + + self.assertEqual(llm.calls, 1) + self.assertEqual(llm.prompt_count, 1) + self.assertIn('"sample_type": "QA"', llm.prompts[0]) + self.assertIn('"question": "q"', llm.prompts[0]) + self.assertIn('"answer": "a"', llm.prompts[0]) + self.assertIn('"question_present": true', llm.prompts[0]) + self.assertIn('"answer_present": true', llm.prompts[0]) + self.assertIn("禁止把该字段判定为空", llm.prompts[0]) + self.assertNotIn('"rationale"', llm.prompts[0]) + self.assertNotIn('"raw_content"', llm.prompts[0]) + self.assertEqual(results[0]["scores"][dimension]["score"], 1) + + def test_rule_backend_does_not_call_llm_generate(self): + class FailingLLM: + def generate(self, prompts, sampling_params): + raise AssertionError("rule backend must not call LLM.generate") + + evaluator = MedicalDataEvaluator( + model_path=None, + llm_instance=FailingLLM(), + backend="rule", + ) + dimension = next(iter(evaluator.dimension_criteria)) + + results = evaluator.evaluate( + [{"id": 1, "type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}], + target_dimensions=[dimension], + ) + + self.assertIn(dimension, results[0]["scores"]) + + def test_vllm_backend_corrects_obvious_empty_field_misread(self): + class EmptyFieldMisreadLLM: + def generate(self, prompts, sampling_params): + return [ + _FakeResult(json.dumps({"score": 0, "reason": "问题和答案字段内容为空"})) + for _ in prompts + ] + + evaluator = MedicalDataEvaluator( + model_path=None, + llm_instance=EmptyFieldMisreadLLM(), + backend="vllm", + ) + dimension = next(iter(evaluator.dimension_criteria)) + + results = evaluator.evaluate( + [{"id": 1, "type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}], + target_dimensions=[dimension], + ) + + self.assertEqual(results[0]["scores"][dimension]["score"], 1) + self.assertIn("llm_consistency_corrected", results[0]["scores"][dimension]["reason"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/Dockerfile b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/Dockerfile new file mode 100644 index 00000000..76a0f760 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/Dockerfile @@ -0,0 +1,18 @@ +ARG BASE_IMAGE=quay.io/ascend/vllm-ascend:v0.18.0rc1 +FROM ${BASE_IMAGE} + +WORKDIR /app + +COPY data_synthesis_service/requirements-base.txt /tmp/requirements-base.txt +COPY data_synthesis_service/requirements.txt /tmp/requirements.txt +COPY data_synthesis_service/requirements-npu.txt /tmp/requirements-npu.txt +ARG REQUIREMENTS_FILE=requirements.txt +RUN python -m pip install --no-cache-dir --no-deps -r /tmp/${REQUIREMENTS_FILE} + +COPY data_synthesis /app/data_synthesis +COPY data_synthesis_service /app/data_synthesis_service + +ENV PYTHONPATH=/app +EXPOSE 18080 + +CMD ["bash", "-lc", "set -e; unset ASCEND_LAUNCH_BLOCKING; export HCCL_OP_EXPANSION_MODE=AIV; source /usr/local/Ascend/ascend-toolkit/set_env.sh; exec python -m uvicorn data_synthesis_service.app:app --host 0.0.0.0 --port 18080"] diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/README.md b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/README.md new file mode 100644 index 00000000..0351dd3d --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/README.md @@ -0,0 +1,43 @@ +# data\_synthesis\_service 服务补丁 + +本目录归档独立 HTTP 服务中与数据质量评估相关的代码。 + +## 接口 + +- `GET /health` +- `POST /synthesize-file` +- `POST /evaluate-file` + +## 本地启动示例 + +```bash +python -m uvicorn data_synthesis_service.app:app --host 0.0.0.0 --port 18080 +``` + +## 依赖 + +- `requirements.txt` 是独立服务生产依赖。 +- 基础镜像为 `quay.io/ascend/vllm-ascend:v0.18.0rc1`,对应 Python `3.11.14`、CANN `8.5.1`。 +- 关键版本包括 `vllm==0.18.0+empty`、`vllm_ascend==0.18.0rc1`、`torch==2.9.0+cpu`、`torch_npu==2.9.0.post1+gitee7ba04`。 +- `requirements-base.txt` 只用于无模型接口冒烟测试。 +- DataMate 算子本体依赖在 `operator_src/requirements.txt`。 + +正式 NPU 构建示例: + +```bash +docker build -t data-synthesis-service:latest \ + -f data_synthesis_service/Dockerfile . +``` + +不传构建参数时默认使用基础镜像并安装 `requirements.txt`。无模型接口冒烟测试可显式增加 `--build-arg REQUIREMENTS_FILE=requirements-base.txt`。 + +Dockerfile 使用 `pip install --no-deps`。这是为了保留 `quay.io/ascend/vllm-ascend:v0.18.0rc1` 中已经验证的 vLLM-Ascend 依赖闭包,避免 pip 重新解析传递依赖导致版本漂移。 + +## 模型路径 + +启动服务前通过环境变量指定容器内模型路径: + +- `DATA_SYNTHESIS_MODEL_PATH` +- `DATA_EVALUATOR_MODEL_PATH` + +默认模型挂载点为容器内 `/model`。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/__init__.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/__init__.py new file mode 100644 index 00000000..dee6f9b5 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/__init__.py @@ -0,0 +1,4 @@ +from .app import app, create_app +from .core import SynthesisService + +__all__ = ["app", "create_app", "SynthesisService"] diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/app.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/app.py new file mode 100644 index 00000000..b502c8ff --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/app.py @@ -0,0 +1,78 @@ +from typing import List, Optional + +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel, Field + +from .core import SynthesisService + + +class HealthRequest(BaseModel): + pass + + +class SynthesizeFileRequest(BaseModel): + file_name: str = Field(..., min_length=1) + text: str = Field(..., min_length=1) + task_types: Optional[List[str]] = None + include_metrics: bool = True + + +class EvaluateFileRequest(BaseModel): + file_name: str = Field(..., min_length=1) + text: str = Field(..., min_length=1) + target_dimensions: Optional[List[str]] = None + include_summary: bool = True + model_path: Optional[str] = None + backend: Optional[str] = None + + +def create_app(service: Optional[SynthesisService] = None) -> FastAPI: + app = FastAPI(title="data_synthesis_service", version="1.0.0") + active_service = service or SynthesisService() + + @app.get("/health") + def health_get() -> dict: + return active_service.health() + + @app.post("/health") + def health(_: HealthRequest) -> dict: + return active_service.health() + + @app.post("/synthesize-file") + def synthesize_file(request: SynthesizeFileRequest) -> dict: + try: + return active_service.synthesize_text( + file_name=request.file_name, + text=request.text, + task_types=request.task_types, + include_metrics=request.include_metrics, + ) + except ValueError as exc: + raise HTTPException(status_code=400, detail=str(exc)) from exc + except RuntimeError as exc: + raise HTTPException(status_code=503, detail=str(exc)) from exc + except Exception as exc: + raise HTTPException(status_code=500, detail=str(exc)) from exc + + @app.post("/evaluate-file") + def evaluate_file(request: EvaluateFileRequest) -> dict: + try: + return active_service.evaluate_text( + file_name=request.file_name, + text=request.text, + target_dimensions=request.target_dimensions, + include_summary=request.include_summary, + model_path=request.model_path, + backend=request.backend, + ) + except ValueError as exc: + raise HTTPException(status_code=400, detail=str(exc)) from exc + except RuntimeError as exc: + raise HTTPException(status_code=503, detail=str(exc)) from exc + except Exception as exc: + raise HTTPException(status_code=500, detail=str(exc)) from exc + + return app + + +app = create_app() diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/core.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/core.py new file mode 100644 index 00000000..2ec510b1 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/core.py @@ -0,0 +1,607 @@ +import json +import os +import subprocess +import sys +import time +from dataclasses import dataclass +from typing import Any, Dict, Iterable, List, Optional + + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +PROJECT_ROOT = os.path.dirname(CURRENT_DIR) +DATA_SYNTHESIS_DIR = os.path.join(PROJECT_ROOT, "data_synthesis") +if DATA_SYNTHESIS_DIR not in sys.path: + sys.path.insert(0, DATA_SYNTHESIS_DIR) + +from data_evaluator import MedicalDataEvaluator +from data_synthesizer import MedicalDataSynthesizer +from requirement_metrics import calculate_generation_metrics, check_project_targets + + +SUPPORTED_TASK_TYPES = ("QA", "CoT", "Preference") +DEFAULT_EVALUATION_DIMENSIONS = ("准确性", "相关性", "安全性", "多样性", "完整性") +DEFAULT_EVALUATOR_MODEL_PATH = "/model/Qwen/Qwen2.5-7B-Instruct" + + +@dataclass +class _GeneratedCandidate: + text: str + + +@dataclass +class _GeneratedResult: + outputs: List[_GeneratedCandidate] + + +class TransformersLLMAdapter: + def __init__(self, model_path: str) -> None: + try: + import torch + from transformers import AutoModelForCausalLM, AutoTokenizer + except Exception as exc: # pragma: no cover + raise ImportError(f"transformers backend unavailable: {exc}") from exc + + self._torch = torch + self._device = "cpu" + model_dtype = torch.float32 + try: + import torch_npu # noqa: F401 + + if hasattr(torch, "npu") and torch.npu.is_available(): + self._device = "npu:0" + model_dtype = torch.float16 + except Exception: + self._device = "cpu" + + self._tokenizer = AutoTokenizer.from_pretrained( + model_path, + trust_remote_code=True, + ) + self._model = AutoModelForCausalLM.from_pretrained( + model_path, + trust_remote_code=True, + torch_dtype=model_dtype, + ) + if self._device != "cpu": + self._model = self._model.to(self._device) + + self._model.eval() + + def generate(self, prompts: List[str], sampling_params: Any) -> List[_GeneratedResult]: + max_new_tokens = int(getattr(sampling_params, "kwargs", {}).get("max_tokens", 256)) + temperature = float(getattr(sampling_params, "kwargs", {}).get("temperature", 0.1)) + top_p = float(getattr(sampling_params, "kwargs", {}).get("top_p", 0.9)) + repetition_penalty = float(getattr(sampling_params, "kwargs", {}).get("repetition_penalty", 1.0)) + + outputs: List[_GeneratedResult] = [] + for prompt in prompts: + model_inputs = self._tokenizer(prompt, return_tensors="pt") + if self._device != "cpu": + model_inputs = {k: v.to(self._device) for k, v in model_inputs.items()} + + with self._torch.no_grad(): + generated_ids = self._model.generate( + **model_inputs, + do_sample=temperature > 0, + temperature=max(temperature, 1e-5), + top_p=top_p, + repetition_penalty=repetition_penalty, + max_new_tokens=max_new_tokens, + pad_token_id=self._tokenizer.eos_token_id, + ) + + prompt_len = model_inputs["input_ids"].shape[1] + new_tokens = generated_ids[0][prompt_len:] + text = self._tokenizer.decode(new_tokens, skip_special_tokens=False) + outputs.append(_GeneratedResult(outputs=[_GeneratedCandidate(text=text)])) + return outputs + + +def _normalize_task_types(task_types: Optional[Iterable[str]]) -> List[str]: + if task_types is None: + return list(SUPPORTED_TASK_TYPES) + normalized = [task_type.strip() for task_type in task_types if str(task_type).strip()] + invalid = [task_type for task_type in normalized if task_type not in SUPPORTED_TASK_TYPES] + if invalid: + raise ValueError(f"Unsupported task_types: {invalid}") + if not normalized: + raise ValueError("task_types must not be empty") + return normalized + + +def _normalize_dimensions(target_dimensions: Optional[Iterable[str]]) -> List[str]: + if target_dimensions is None: + return list(DEFAULT_EVALUATION_DIMENSIONS) + normalized = [str(dim).strip() for dim in target_dimensions if str(dim).strip()] + invalid = [dim for dim in normalized if dim not in DEFAULT_EVALUATION_DIMENSIONS] + if invalid: + raise ValueError(f"Unsupported target_dimensions: {invalid}") + if not normalized: + raise ValueError("target_dimensions must not be empty") + return normalized + + +def _make_record(record_id: int, task_type: str, payload: Dict[str, Any]) -> Dict[str, Any]: + return { + "id": record_id, + "type": task_type, + "content": json.dumps(payload, ensure_ascii=False), + } + + +def _records_from_synthesis_payload(payload: Dict[str, Any]) -> List[Dict[str, Any]]: + records: List[Dict[str, Any]] = [] + next_id = 1 + results = payload.get("results", {}) + if not isinstance(results, dict): + return records + + for task_type in SUPPORTED_TASK_TYPES: + items = results.get(task_type, []) + if not isinstance(items, list): + continue + for item in items: + data = item + if isinstance(item, dict) and "data" in item: + if item.get("status") != "success": + continue + data = item.get("data", {}) + if not isinstance(data, dict): + continue + records.append(_make_record(next_id, task_type, data)) + next_id += 1 + return records + + +def _parse_evaluation_input(text: str) -> List[Dict[str, Any]]: + raw = (text or "").strip() + if not raw: + raise ValueError("text must not be empty") + + try: + parsed = json.loads(raw) + except json.JSONDecodeError as exc: + raise ValueError("evaluation input must be JSON text") from exc + + if isinstance(parsed, dict) and "results" in parsed: + records = _records_from_synthesis_payload(parsed) + if records: + return records + raise ValueError("No successful generated records found in synthesis results") + + if isinstance(parsed, dict) and isinstance(parsed.get("records"), list): + parsed = parsed["records"] + + if isinstance(parsed, dict) and "content" in parsed: + parsed = [parsed] + + if not isinstance(parsed, list): + raise ValueError("evaluation input must be a JSON array, a record object, or synthesis results JSON") + + records: List[Dict[str, Any]] = [] + for idx, item in enumerate(parsed, start=1): + if not isinstance(item, dict): + raise ValueError("Each evaluation record must be a JSON object") + content = item.get("content") + if isinstance(content, dict): + task_type = str(item.get("type") or "QA") + records.append(_make_record(int(item.get("id") or idx), task_type, content)) + continue + if not isinstance(content, str) or not content.strip(): + raise ValueError("Each evaluation record must contain non-empty content") + records.append( + { + "id": int(item.get("id") or idx), + "type": str(item.get("type") or "QA"), + "content": content, + } + ) + + if not records: + raise ValueError("No evaluation records found") + return records + + +class SynthesisService: + def __init__( + self, + model_path: Optional[str] = None, + evaluator_model_path: Optional[str] = None, + synthesizer: Any = None, + evaluator: Any = None, + ) -> None: + self.model_path = model_path or os.environ.get("DATA_SYNTHESIS_MODEL_PATH") or os.environ.get("MODEL_PATH") + self.evaluator_model_path = ( + evaluator_model_path + or os.environ.get("DATA_EVALUATOR_MODEL_PATH") + or DEFAULT_EVALUATOR_MODEL_PATH + ) + self.backend = os.environ.get("DATA_SYNTHESIS_BACKEND", "auto").lower() + self.run_mode = os.environ.get("DATA_SYNTHESIS_RUN_MODE", "inprocess").lower() + self._ready = False + self._init_error: Optional[str] = "Service not initialized" + self._synthesizer_error: Optional[str] = None + self._evaluator_error: Optional[str] = None + self.synthesizer = synthesizer + self.evaluator = evaluator + self.evaluator_backend = ( + os.environ.get("DATA_EVALUATOR_BACKEND") + or "vllm" + ).strip().lower() + + def _initialize_components(self) -> None: + try: + self.synthesizer = self.synthesizer or self._build_synthesizer() + self._ready = True + self._init_error = None + except Exception as exc: + self._ready = False + self._init_error = str(exc) + + def _ensure_synthesizer_initialized(self) -> None: + if self.synthesizer is not None: + self._ready = True + self._init_error = None + return + try: + self.synthesizer = self._build_synthesizer() + self._ready = True + self._init_error = None + self._synthesizer_error = None + except Exception as exc: + self._ready = False + self._init_error = str(exc) + self._synthesizer_error = str(exc) + + def _ensure_evaluator_initialized(self, backend: Optional[str] = None) -> None: + requested_backend = (backend or self.evaluator_backend or "vllm").strip().lower() + current_backend = getattr(self.evaluator, "backend", None) + if self.evaluator is not None and current_backend in (None, requested_backend): + self._evaluator_error = None + return + try: + self.evaluator = MedicalDataEvaluator( + self.evaluator_model_path, + backend=requested_backend, + ) + self._evaluator_error = None + except Exception as exc: + self._evaluator_error = str(exc) + raise + + def _ensure_initialized(self) -> None: + if self._ready and self.synthesizer is not None: + return + self._ensure_synthesizer_initialized() + if not self._ready: + self._ensure_synthesizer_initialized() + + def health(self) -> Dict[str, Any]: + if self.run_mode != "subprocess": + self._ensure_initialized() + return { + "service": "data_synthesis", + "ready": True if self.run_mode == "subprocess" else self._ready, + "model_path": self.model_path, + "evaluator_model_path": self.evaluator_model_path, + "backend": self.backend, + "evaluator_backend": self.evaluator_backend, + "error": None if self.run_mode == "subprocess" else self._init_error, + } + + def _build_synthesizer(self) -> MedicalDataSynthesizer: + if not self.model_path: + raise ValueError("model_path is required") + + if self.backend == "transformers": + return MedicalDataSynthesizer( + self.model_path, + llm_instance=TransformersLLMAdapter(self.model_path), + ) + + if self.backend == "vllm": + return MedicalDataSynthesizer(self.model_path) + + try: + return MedicalDataSynthesizer(self.model_path) + except Exception: + return MedicalDataSynthesizer( + self.model_path, + llm_instance=TransformersLLMAdapter(self.model_path), + ) + + def synthesize_text( + self, + file_name: str, + text: str, + task_types: Optional[Iterable[str]] = None, + include_metrics: bool = True, + ) -> Dict[str, Any]: + if self.run_mode == "subprocess": + return self._synthesize_via_subprocess( + file_name=file_name, + text=text, + task_types=task_types, + include_metrics=include_metrics, + ) + + self._ensure_initialized() + if not self._ready or self.synthesizer is None: + raise RuntimeError(self._init_error or "Service is not ready") + + normalized_text = (text or "").strip() + if not normalized_text: + raise ValueError("text must not be empty") + + normalized_task_types = _normalize_task_types(task_types) + results: Dict[str, List[Dict[str, Any]]] = {task_type: [] for task_type in SUPPORTED_TASK_TYPES} + records: List[Dict[str, Any]] = [] + evaluation_inputs: List[Dict[str, Any]] = [] + + for task_type in normalized_task_types: + started_at = time.time() + batch_results = self.synthesizer.generate_data_batch(task_type, [normalized_text]) + elapsed = time.time() - started_at + per_item_latency = elapsed / max(len(batch_results), 1) + results[task_type] = batch_results + + for item in batch_results: + record = { + "task_type": task_type, + "status": item.get("status", "failed"), + "latency": per_item_latency, + "data": item.get("data", {}), + } + records.append(record) + if item.get("status") == "success": + evaluation_inputs.append( + { + "type": task_type, + "content": json.dumps(item.get("data", {}), ensure_ascii=False), + } + ) + + metrics: Dict[str, Any] = {} + if include_metrics: + metrics = self._build_metrics(records, evaluation_inputs) + + return { + "source_file": file_name, + "task_types": normalized_task_types, + "results": results, + "metrics": metrics, + "status": "success", + } + + def evaluate_text( + self, + file_name: str, + text: str, + target_dimensions: Optional[Iterable[str]] = None, + include_summary: bool = True, + model_path: Optional[str] = None, + backend: Optional[str] = None, + ) -> Dict[str, Any]: + if self.run_mode == "subprocess": + return self._evaluate_via_subprocess( + file_name=file_name, + text=text, + target_dimensions=target_dimensions, + include_summary=include_summary, + model_path=model_path, + backend=backend, + ) + + if model_path and model_path != self.evaluator_model_path: + self.evaluator_model_path = model_path + self.evaluator = None + try: + self._ensure_evaluator_initialized(backend or self.evaluator_backend or "vllm") + except Exception as exc: + raise RuntimeError(str(exc)) from exc + if self.evaluator is None: + raise RuntimeError(self._init_error or "Evaluator is not ready") + + records = _parse_evaluation_input(text) + dimensions = _normalize_dimensions(target_dimensions) + evaluation_results = self.evaluator.evaluate(records, target_dimensions=dimensions) + + response: Dict[str, Any] = { + "source_file": file_name, + "record_count": len(records), + "dimensions": dimensions, + "results": evaluation_results, + "runtime": ( + self.evaluator.runtime_metadata() + if hasattr(self.evaluator, "runtime_metadata") + else { + "evaluator_backend": getattr(self.evaluator, "backend", "unknown"), + "evaluator_model_path": self.evaluator_model_path, + "vllm_enabled": getattr(self.evaluator, "backend", None) == "vllm", + } + ), + "status": "success", + } + if include_summary: + response["summary"] = self._build_evaluation_summary(records, evaluation_results, dimensions) + return response + + def _synthesize_via_subprocess( + self, + file_name: str, + text: str, + task_types: Optional[Iterable[str]], + include_metrics: bool, + ) -> Dict[str, Any]: + normalized_task_types = _normalize_task_types(task_types) + worker_payload = { + "file_name": file_name, + "text": text, + "task_types": normalized_task_types, + "include_metrics": include_metrics, + "model_path": self.model_path, + "backend": self.backend, + } + worker_code = """ +import json +import os +import sys +payload = json.loads(sys.stdin.read()) +os.environ["DATA_SYNTHESIS_MODEL_PATH"] = payload["model_path"] or "" +os.environ["DATA_SYNTHESIS_BACKEND"] = payload["backend"] +from data_synthesis_service.core import SynthesisService +service = SynthesisService(model_path=payload["model_path"]) +result = service.synthesize_text( + file_name=payload["file_name"], + text=payload["text"], + task_types=payload["task_types"], + include_metrics=payload["include_metrics"], +) +print(json.dumps(result, ensure_ascii=False)) +""" + env = os.environ.copy() + env["DATA_SYNTHESIS_RUN_MODE"] = "inprocess" + completed = subprocess.run( + [sys.executable, "-c", worker_code], + input=json.dumps(worker_payload, ensure_ascii=False), + text=True, + capture_output=True, + env=env, + cwd=PROJECT_ROOT, + check=False, + ) + if completed.returncode != 0: + error_text = (completed.stderr or completed.stdout or "subprocess failed").strip() + raise RuntimeError(error_text) + output_lines = [line.strip() for line in completed.stdout.splitlines() if line.strip()] + if not output_lines: + raise RuntimeError("subprocess returned empty output") + return json.loads(output_lines[-1]) + + def _evaluate_via_subprocess( + self, + file_name: str, + text: str, + target_dimensions: Optional[Iterable[str]], + include_summary: bool, + model_path: Optional[str], + backend: Optional[str] = None, + ) -> Dict[str, Any]: + normalized_dimensions = _normalize_dimensions(target_dimensions) + worker_payload = { + "action": "evaluate", + "file_name": file_name, + "text": text, + "target_dimensions": normalized_dimensions, + "include_summary": include_summary, + "model_path": model_path or self.evaluator_model_path, + "synthesis_model_path": self.model_path, + "backend": self.backend, + "evaluator_backend": backend or self.evaluator_backend or "vllm", + } + return self._run_subprocess_worker(worker_payload) + + def _run_subprocess_worker(self, worker_payload: Dict[str, Any]) -> Dict[str, Any]: + worker_code = """ +import json +import os +import sys +payload = json.loads(sys.stdin.read()) +os.environ["DATA_SYNTHESIS_MODEL_PATH"] = payload.get("synthesis_model_path") or payload.get("model_path") or "" +os.environ["DATA_EVALUATOR_MODEL_PATH"] = payload.get("model_path") or "" +os.environ["DATA_SYNTHESIS_BACKEND"] = payload.get("backend") or "auto" +os.environ["DATA_EVALUATOR_BACKEND"] = payload.get("evaluator_backend") or "vllm" +from data_synthesis_service.core import SynthesisService +service = SynthesisService( + model_path=payload.get("synthesis_model_path"), + evaluator_model_path=payload.get("model_path"), +) +action = payload.get("action") +if action == "synthesize": + result = service.synthesize_text( + file_name=payload["file_name"], + text=payload["text"], + task_types=payload["task_types"], + include_metrics=payload["include_metrics"], + ) +elif action == "evaluate": + result = service.evaluate_text( + file_name=payload["file_name"], + text=payload["text"], + target_dimensions=payload["target_dimensions"], + include_summary=payload["include_summary"], + model_path=payload.get("model_path"), + backend=payload.get("evaluator_backend"), + ) +else: + raise RuntimeError(f"Unsupported action: {action}") +print(json.dumps(result, ensure_ascii=False)) +""" + env = os.environ.copy() + env["DATA_SYNTHESIS_RUN_MODE"] = "inprocess" + completed = subprocess.run( + [sys.executable, "-c", worker_code], + input=json.dumps(worker_payload, ensure_ascii=False), + text=True, + capture_output=True, + env=env, + cwd=PROJECT_ROOT, + check=False, + ) + if completed.returncode != 0: + error_text = (completed.stderr or completed.stdout or "subprocess failed").strip() + raise RuntimeError(error_text) + output_lines = [line.strip() for line in completed.stdout.splitlines() if line.strip()] + if not output_lines: + raise RuntimeError("subprocess returned empty output") + return json.loads(output_lines[-1]) + + def _build_metrics( + self, + records: List[Dict[str, Any]], + evaluation_inputs: List[Dict[str, Any]], + ) -> Dict[str, Any]: + try: + self._ensure_evaluator_initialized("rule") + evaluator_scores = self.evaluator.evaluate(evaluation_inputs) if evaluation_inputs else [] + summary = calculate_generation_metrics(records, evaluator_scores) + return { + "ready": True, + "summary": summary, + "targets": check_project_targets(summary), + } + except Exception as exc: + return {"ready": False, "error": str(exc)} + + def _build_evaluation_summary( + self, + records: List[Dict[str, Any]], + evaluation_results: List[Dict[str, Any]], + dimensions: List[str], + ) -> Dict[str, Any]: + per_dimension: Dict[str, Dict[str, Any]] = {} + for dim in dimensions: + scores = [] + for item in evaluation_results: + score = item.get("scores", {}).get(dim, {}).get("score", -1) + if isinstance(score, int) and score >= 0: + scores.append(score) + pass_count = sum(1 for score in scores if score == 1) + total = len(scores) + pass_rate = (pass_count / total * 100.0) if total else 0.0 + per_dimension[dim] = { + "pass_count": pass_count, + "total": total, + "pass_rate_pct": pass_rate, + } + + task_type_counts: Dict[str, int] = {} + for record in records: + task_type = str(record.get("type") or "QA") + task_type_counts[task_type] = task_type_counts.get(task_type, 0) + 1 + + return { + "record_count": len(records), + "task_type_counts": task_type_counts, + "dimensions": per_dimension, + } diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements-base.txt b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements-base.txt new file mode 100644 index 00000000..29ad47ad --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements-base.txt @@ -0,0 +1,7 @@ +# HTTP service base dependencies for smoke tests without model inference. +# Versions are aligned with 910b-jss huizhi:test-v018. +fastapi==0.123.10 +uvicorn==0.42.0 +pydantic==2.12.5 +Jinja2==3.1.6 +requests==2.33.1 diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements.txt b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements.txt new file mode 100644 index 00000000..d857a7bc --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements.txt @@ -0,0 +1,16 @@ +fastapi==0.123.10 +uvicorn==0.42.0 +pydantic==2.12.5 +Jinja2==3.1.6 +requests==2.33.1 +vllm==0.18.0+empty +vllm_ascend==0.18.0rc1 +torch==2.9.0+cpu +torch_npu==2.9.0.post1+gitee7ba04 +transformers==4.57.6 +tokenizers==0.22.2 +sentencepiece==0.2.1 +einops==0.8.2 +numpy==1.26.4 +safetensors==0.7.0 +typing_extensions==4.15.0 diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/tests/test_app.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/tests/test_app.py new file mode 100644 index 00000000..d4935cb8 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/tests/test_app.py @@ -0,0 +1,96 @@ +import os +import sys +import unittest + +from fastapi.testclient import TestClient + + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +PROJECT_ROOT = os.path.dirname(os.path.dirname(CURRENT_DIR)) +if PROJECT_ROOT not in sys.path: + sys.path.insert(0, PROJECT_ROOT) + +from data_synthesis_service.app import create_app + + +class _FakeService: + def health(self): + return {"ready": True, "model_path": "/models/demo", "service": "data_synthesis"} + + def synthesize_text(self, file_name, text, task_types=None, include_metrics=True): + return { + "source_file": file_name, + "task_types": task_types or ["QA", "CoT", "Preference"], + "results": {"QA": [], "CoT": [], "Preference": []}, + "metrics": {} if include_metrics else None, + "status": "success", + } + + def evaluate_text( + self, + file_name, + text, + target_dimensions=None, + include_summary=True, + model_path=None, + backend=None, + ): + return { + "source_file": file_name, + "record_count": 1, + "dimensions": target_dimensions or ["准确性", "相关性", "安全性", "多样性", "完整性"], + "results": [{"id": 1, "scores": {"准确性": {"score": 1, "reason": "ok"}}}], + "summary": {"record_count": 1} if include_summary else None, + "model_path": model_path, + "status": "success", + } + + +class AppTests(unittest.TestCase): + def test_health_endpoint(self): + client = TestClient(create_app(service=_FakeService())) + response = client.post("/health", json={}) + self.assertEqual(response.status_code, 200) + self.assertTrue(response.json()["ready"]) + + def test_health_endpoint_supports_get(self): + client = TestClient(create_app(service=_FakeService())) + response = client.get("/health") + self.assertEqual(response.status_code, 200) + self.assertTrue(response.json()["ready"]) + + def test_synthesize_endpoint(self): + client = TestClient(create_app(service=_FakeService())) + response = client.post( + "/synthesize-file", + json={"file_name": "demo.txt", "text": "abc"}, + ) + self.assertEqual(response.status_code, 200) + payload = response.json() + self.assertEqual(payload["source_file"], "demo.txt") + self.assertEqual(payload["status"], "success") + + def test_evaluate_endpoint(self): + client = TestClient(create_app(service=_FakeService())) + response = client.post( + "/evaluate-file", + json={"file_name": "demo.json", "text": '{"content":"{}"}'}, + ) + self.assertEqual(response.status_code, 200) + payload = response.json() + self.assertEqual(payload["source_file"], "demo.json") + self.assertEqual(payload["status"], "success") + + def test_evaluate_endpoint_accepts_dedicated_model_path(self): + client = TestClient(create_app(service=_FakeService())) + response = client.post( + "/evaluate-file", + json={ + "file_name": "demo.json", + "text": '{"content":"{}"}', + "model_path": "/model/Qwen/Qwen2.5-7B-Instruct", + }, + ) + self.assertEqual(response.status_code, 200) + payload = response.json() + self.assertEqual(payload["model_path"], "/model/Qwen/Qwen2.5-7B-Instruct") diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/tests/test_evaluator_backend_service.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/tests/test_evaluator_backend_service.py new file mode 100644 index 00000000..a8beae25 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/tests/test_evaluator_backend_service.py @@ -0,0 +1,76 @@ +import json +import os +import sys +import unittest +from unittest.mock import patch + + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +PROJECT_ROOT = os.path.dirname(os.path.dirname(CURRENT_DIR)) +if PROJECT_ROOT not in sys.path: + sys.path.insert(0, PROJECT_ROOT) + +from data_synthesis_service.core import DEFAULT_EVALUATION_DIMENSIONS, SynthesisService + + +class _FakeSynthesizer: + pass + + +class _FakeEvaluator: + def __init__(self, backend): + self.backend = backend + self.model_path = "/model/evaluator" + + def evaluate(self, data_list, target_dimensions=None): + dimensions = list(target_dimensions or DEFAULT_EVALUATION_DIMENSIONS) + return [ + { + "id": 1, + "scores": { + dimension: {"score": 1, "reason": "ok"} + for dimension in dimensions + }, + } + ] + + def runtime_metadata(self): + return { + "evaluator_backend": self.backend, + "evaluator_model_path": self.model_path, + "vllm_enabled": self.backend == "vllm", + "visible_npus": "6", + } + + +class EvaluatorBackendServiceTests(unittest.TestCase): + @patch("data_synthesis_service.core.MedicalDataEvaluator") + def test_evaluate_file_initializes_evaluator_with_vllm_backend(self, evaluator_cls): + evaluator_cls.side_effect = lambda model_path, **kwargs: _FakeEvaluator(kwargs["backend"]) + service = SynthesisService(synthesizer=_FakeSynthesizer()) + + result = service.evaluate_text( + "records.json", + json.dumps([{"id": 1, "type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}]), + ) + + self.assertEqual(evaluator_cls.call_args.kwargs["backend"], "vllm") + self.assertEqual(result["runtime"]["evaluator_backend"], "vllm") + self.assertTrue(result["runtime"]["vllm_enabled"]) + + @patch("data_synthesis_service.core.MedicalDataEvaluator") + def test_metrics_initializes_rule_backend(self, evaluator_cls): + evaluator_cls.side_effect = lambda model_path, **kwargs: _FakeEvaluator(kwargs["backend"]) + service = SynthesisService(synthesizer=_FakeSynthesizer()) + + metrics = service._build_metrics( + records=[{"task_type": "QA", "status": "success", "latency": 1.0, "data": {"question": "q", "answer": "a"}}], + evaluation_inputs=[{"type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}], + ) + + self.assertEqual(evaluator_cls.call_args.kwargs["backend"], "rule") + self.assertTrue(metrics["ready"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/README.md b/runtime/ops/mapper/data_quality_evaluator/test_cases/README.md new file mode 100644 index 00000000..1e214b82 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/README.md @@ -0,0 +1,40 @@ +# data_quality_evaluator 测试用例 + +本目录提供公开数据集来源说明和轻量评估样例,用于验收平台复测数据质量评估算子。 + +## 公开数据集来源 + +- `cMedQA2` + 中文医学问答数据集,适合验证中文医学 QA 质量评估。 + + +- `PubMedQA` + 生物医学问答数据集,适合验证专业医学问答质量评估。 + + + + +## 本目录样例 + +- `example_input/public_eval_cases.json` + 包含 `QA`、`CoT`、`Preference` 三类记录,并包含明显合格与明显不合格样本。 +- `cases.json` + 记录测试样例来源、目标维度和验收检查点。 + +## 平台测试步骤 + +1. 部署带评估接口的独立服务,确认 DataMate 运行环境能访问服务地址。 +2. 在 DataMate 算子市场上传 `../data_quality_evaluator.zip`。 +3. 创建任务并上传 `example_input/public_eval_cases.json`。 +4. 算子参数使用: + - `targetDimensions=accuracy,relevance,safety,diversity,completeness` + - `evaluatorBackend=vllm` +5. 运行任务并下载输出 JSON。 + +## 检查项 + +- 输出 JSON 包含 `source_file`、`record_count`、`dimensions`、`results`、`summary`、`status`。 +- 每条记录包含 5 个维度评分和理由。 +- 明显错误或高风险医学内容应在 `准确性` 或 `安全性` 上给出 0 分。 +- 合格样本多数维度应给出 1 分。 +- `summary.task_type_counts` 与输入样本类型统计一致。 diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/cases.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/cases.json new file mode 100644 index 00000000..44972b27 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/cases.json @@ -0,0 +1,25 @@ +[ + { + "id": "mixed_quality_medical_records", + "operator": "data_quality_evaluator", + "dataset_basis": [ + "cMedQA2", + "PubMedQA" + ], + "input_file": "example_input/public_eval_cases.json", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2", + "https://huggingface.co/datasets/fzkuji/cMedQA2", + "https://github.com/pubmedqa/pubmedqa", + "https://huggingface.co/datasets/qiaojin/PubMedQA", + "https://arxiv.org/abs/1909.06146" + ], + "purpose": "验证评估算子对好坏样本的区分能力,以及 QA/CoT/Preference 三类结构的兼容性", + "checks": [ + "record_count 与输入记录数一致", + "results 中每条记录含 5 个维度分数", + "明显错误答案至少在准确性或安全性上判 0", + "summary.task_type_counts 正确" + ] + } +] diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/public_eval_cases.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/public_eval_cases.json new file mode 100644 index 00000000..585181b1 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/public_eval_cases.json @@ -0,0 +1,37 @@ +[ + { + "id": 1, + "type": "QA", + "content": { + "question": "高血压患者日常应如何进行家庭血压监测?", + "answer": "建议每天在固定时间测量血压并记录,注意低盐饮食、规律运动,按医嘱服药并定期复诊。" + } + }, + { + "id": 2, + "type": "QA", + "content": { + "question": "青霉素过敏患者还能继续使用阿莫西林吗?", + "answer": "可以继续使用阿莫西林,无需担心过敏。" + } + }, + { + "id": 3, + "type": "CoT", + "content": { + "question": "患者发热、咳嗽 3 天,伴咽痛,无呼吸困难,首先应如何处理?", + "rationale": "需要先评估病情严重程度和危险信号,再结合症状进行初步分层。当前没有明显呼吸衰竭表现,优先建议就医评估并进行必要检查,同时给予对症处理建议。", + "final_answer": "建议尽快到正规医疗机构就诊,评估是否为上呼吸道感染,并在医生指导下进行检查与治疗;若出现呼吸困难或持续高热,应及时急诊处理。" + } + }, + { + "id": 4, + "type": "Preference", + "content": { + "question": "高血压患者日常应如何进行家庭血压监测?", + "chosen": "建议在固定时间测量并长期记录血压,配合低盐饮食、规律运动和按医嘱复诊。", + "rejected": "想起来就量一下,不需要长期记录。", + "preference_reason": "chosen 更完整,也更符合长期慢病管理要求。" + } + } +] diff --git a/runtime/ops/mapper/data_synthesis/README.md b/runtime/ops/mapper/data_synthesis/README.md new file mode 100644 index 00000000..7d75e992 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/README.md @@ -0,0 +1,118 @@ +# data\_synthesis 算子 + +## 目录内容 + +- `operator_src/`:DataMate 平台轻量算子源码。 +- `service_patch/`:独立数据合成服务代码。 +- `service_image/`:独立服务镜像构建说明和 Dockerfile。 +- `example_input/`:手工联调输入样例。 +- `test_cases/`:公开数据集来源说明、轻量测试输入和测试步骤。 + +## 开源模型链接 + +- 医疗 SFT 模型:[https://www.modelscope.cn/models/zpeng1989/Medical\_Qwen3\_17B\_Large\_Language\_Model](https://www.modelscope.cn/models/zpeng1989/Medical_Qwen3_17B_Large_Language_Model "https://www.modelscope.cn/models/zpeng1989/Medical_Qwen3_17B_Large_Language_Model") +- 公开基座模型 `Qwen/Qwen3-1.7B`:[https://huggingface.co/Qwen/Qwen3-1.7B](https://huggingface.co/Qwen/Qwen3-1.7B "https://huggingface.co/Qwen/Qwen3-1.7B") + +## 调用链路 + +1. DataMate 平台上传轻量算子包 `data_synthesis.zip`。 +2. 算子读取输入文本文件。 +3. 算子通过 HTTP 调用独立服务 `POST /synthesize-file`。 +4. 独立服务加载本地模型,生成 QA、CoT、Preference 三类结果。 +5. 算子将服务返回的 JSON 写入平台输出文件。 + +## 依赖与环境 + +- `operator_src/requirements.txt` 是 DataMate 轻量算子依赖,只包含 HTTP 调用所需依赖,不包含 `vllm`。 +- `service_patch/data_synthesis_service/requirements.txt` 是独立服务生产依赖。 +- 服务基础镜像固定为 `quay.io/ascend/vllm-ascend:v0.18.0rc1`,对应 Python `3.11.14`、CANN `8.5.1`。 +- 关键版本包括 `vllm==0.18.0+empty`、`vllm_ascend==0.18.0rc1`、`torch==2.9.0+cpu`、`torch_npu==2.9.0.post1+gitee7ba04`。 +- `service_patch/data_synthesis_service/requirements-base.txt` 只用于无模型接口冒烟测试,不用于正式验收推理。 + +## 独立服务部署 + +1. 将医疗 SFT 模型下载到验收机器任意目录。 +2. 运行容器时将模型目录挂载到容器内 `/model`。 +3. 使用 `service_image/Dockerfile` 构建独立服务镜像。 +4. 启动服务后,通过 `serviceUrl` 让 DataMate 算子访问该服务。 + +构建镜像: + +```bash +docker build -t data-synthesis-service:latest -f service_image/Dockerfile . +``` + +启动服务: + +```bash +docker run -d --name data-synthesis-service \ + --privileged \ + --security-opt label=disable \ + --network \ + -p 18080:18080 \ + --device /dev/davinci6 \ + --device /dev/davinci_manager \ + --device /dev/devmm_svm \ + --device /dev/hisi_hdc \ + -v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/:ro \ + -v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info:ro \ + -v /etc/ascend_install.info:/etc/ascend_install.info:ro \ + -v /usr/local/dcmi:/usr/local/dcmi:ro \ + -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi:ro \ + -v :/model:ro \ + -e ASCEND_VISIBLE_DEVICES=6 \ + -e ASCEND_RT_VISIBLE_DEVICES=6 \ + -e HCCL_OP_EXPANSION_MODE=AIV \ + -e DATA_SYNTHESIS_MODEL_PATH=/model/Qwen/Qwen3-1___7b-Medical-R1-sft \ + data-synthesis-service:latest +``` + +说明: + +- `` 是验收机器上的模型目录,按实际环境替换。 +- `` 是 DataMate 容器可访问的 Docker 网络;如果不在同一网络,可把算子参数 `serviceUrl` 改成实际可访问地址。 +- `/model` 是容器内模型挂载点,不是主机固定路径。 +- NPU 启动参数默认第 6 号 NPU。使用其他 NPU 时,同步替换 `--device /dev/davinciX`、`ASCEND_VISIBLE_DEVICES` 和 `ASCEND_RT_VISIBLE_DEVICES`。 + +检查服务: + +```bash +curl http://:18080/health +``` + +## 服务接口 + +默认服务地址: + +```text +http://data-synthesis-service:18080 +``` + +主要接口: + +- `GET /health` +- `POST /synthesize-file` +- `POST /evaluate-file` + +## 如何生成 DataMate 上传包 + +压缩 `operator_src/` 目录中的全部文件,生成 `data_synthesis.zip` 后上传 DataMate。 + +压缩包根目录应直接包含: + +- `metadata.yml` +- `process.py` +- `__init__.py` +- `requirements.txt` +- `README.md` + +`service_patch/`、`service_image/`、`example_input/`、`test_cases/` 只用于服务部署和验收测试,不放入 DataMate 算子上传包。 + +## 平台测试 + +1. 部署独立服务并确认 `GET /health` 可访问。 +2. 在 DataMate 算子市场上传按上述规则生成的上传包。 +3. 新建任务,上传 `test_cases/example_input/` 下的文本样例。 +4. 算子参数 `taskTypes` 使用 `QA,CoT,Preference`。 +5. 运行任务并下载输出 JSON。 +6. 按 `test_cases/README.md` 检查三类结果是否存在、字段是否完整,且结果由模型生成,失败时不会伪装为成功。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/example_input/data_synthesis_demo.txt b/runtime/ops/mapper/data_synthesis/example_input/data_synthesis_demo.txt new file mode 100644 index 00000000..4d99986d --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/example_input/data_synthesis_demo.txt @@ -0,0 +1 @@ +患者男,58岁,主诉胸闷胸痛2小时,既往有高血压病史。心电图提示V2-V5导联ST段抬高。 diff --git a/runtime/ops/mapper/data_synthesis/operator_src/README.md b/runtime/ops/mapper/data_synthesis/operator_src/README.md new file mode 100644 index 00000000..4896aa0f --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/operator_src/README.md @@ -0,0 +1,20 @@ +# data_synthesis 算子源码 + +本目录是 DataMate 平台上传包中的算子源码。 + +## 功能 + +- 读取平台传入的一个文本文件。 +- 调用独立部署的 `data_synthesis` 服务。 +- 将服务返回的 QA、CoT、Preference 合成结果写成平台输出 JSON 文件。 + +## 关键参数 + +- `serviceUrl` + 独立服务 HTTP 地址,默认使用容器网络服务名 `http://data-synthesis-service:18080`。 +- `taskTypes` + 生成任务类型,默认 `QA,CoT,Preference`。 +- `includeMetrics` + 是否在输出中包含质量指标。 +- `timeoutSec` + 调用服务的超时时间。 diff --git a/runtime/ops/mapper/data_synthesis/operator_src/__init__.py b/runtime/ops/mapper/data_synthesis/operator_src/__init__.py new file mode 100644 index 00000000..7e3c5791 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/operator_src/__init__.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +try: + from datamate.core.base_op import OPERATORS +except Exception: # pragma: no cover + OPERATORS = None + +if OPERATORS is not None: + OPERATORS.register_module( + module_name="DataSynthesisMapper", + module_path="ops.user.data_synthesis.process", + ) diff --git a/runtime/ops/mapper/data_synthesis/operator_src/metadata.yml b/runtime/ops/mapper/data_synthesis/operator_src/metadata.yml new file mode 100644 index 00000000..d2c383ce --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/operator_src/metadata.yml @@ -0,0 +1,48 @@ +name: 'data_synthesis' +description: 'Call the standalone data_synthesis HTTP service and export one JSON result file.' +language: 'python' +vendor: 'huawei' +raw_id: 'DataSynthesisMapper' +version: '1.0.0' +modal: 'text' +inputs: 'text' +outputs: 'text' +types: + - 'annotation' +release: + - 'Initial standalone-service wrapper for acceptance platform.' +metrics: + - name: 'Output' + metric: '1 JSON file per input text file' +runtime: + memory: 1073741824 + cpu: 0.5 + gpu: 0 + npu: 0 +settings: + serviceUrl: + name: 'Service URL' + description: 'HTTP endpoint of the standalone data_synthesis service.' + type: 'input' + defaultVal: 'http://data-synthesis-service:18080' + required: true + taskTypes: + name: 'Task Types' + description: 'Comma-separated task types. Supported values: QA, CoT, Preference.' + type: 'input' + defaultVal: 'QA,CoT,Preference' + required: true + includeMetrics: + name: 'Include Metrics' + description: 'Whether to include evaluator and requirement metrics in the JSON response.' + type: 'switch' + defaultVal: 'true' + required: false + checkedLabel: 'true' + unCheckedLabel: 'false' + timeoutSec: + name: 'Timeout' + description: 'HTTP request timeout in seconds.' + type: 'input' + defaultVal: '300' + required: true diff --git a/runtime/ops/mapper/data_synthesis/operator_src/process.py b/runtime/ops/mapper/data_synthesis/operator_src/process.py new file mode 100644 index 00000000..d34efc54 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/operator_src/process.py @@ -0,0 +1,98 @@ +import json +import os +from typing import Any, Dict, Iterable, List, Optional + +import requests + +try: + from datamate.core.base_op import Mapper +except Exception: # pragma: no cover + class Mapper: # type: ignore + def __init__(self, *args, **kwargs): + self.text_key = kwargs.get("text_key", "text") + self.filepath_key = kwargs.get("filePath_key", "filePath") + self.filename_key = kwargs.get("fileName_key", "fileName") + self.target_type_key = kwargs.get("target_type_key", "target_type") + + +DEFAULT_SERVICE_URL = "http://data-synthesis-service:18080" +SUPPORTED_TASK_TYPES = {"QA", "CoT", "Preference"} + + +def _parse_task_types(value: Any) -> List[str]: + if value is None or value == "": + return ["QA", "CoT", "Preference"] + if isinstance(value, str): + items = [item.strip() for item in value.split(",") if item.strip()] + else: + items = [str(item).strip() for item in value if str(item).strip()] + invalid = [item for item in items if item not in SUPPORTED_TASK_TYPES] + if invalid: + raise ValueError(f"Unsupported taskTypes: {invalid}") + return items or ["QA", "CoT", "Preference"] + + +def _read_text_from_sample(sample: Dict[str, Any], text_key: str, filepath_key: str) -> str: + text = str(sample.get(text_key, "") or "").strip() + if text: + return text + + file_path = sample.get(filepath_key) + if file_path and os.path.isfile(file_path): + with open(file_path, "r", encoding="utf-8") as file: + return file.read().strip() + return "" + + +def build_service_payload( + sample: Dict[str, Any], + task_types: Iterable[str], + include_metrics: bool, + text_key: str = "text", + filepath_key: str = "filePath", + filename_key: str = "fileName", +) -> Dict[str, Any]: + text = _read_text_from_sample(sample, text_key, filepath_key) + if not text: + raise ValueError("Input text is empty") + return { + "file_name": sample.get(filename_key, "input.txt"), + "text": text, + "task_types": list(task_types), + "include_metrics": include_metrics, + } + + +def serialize_service_response(payload: Dict[str, Any]) -> str: + return json.dumps(payload, ensure_ascii=False, indent=2) + + +class DataSynthesisMapper(Mapper): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.service_url = str(kwargs.get("serviceUrl", DEFAULT_SERVICE_URL)).rstrip("/") + self.task_types = _parse_task_types(kwargs.get("taskTypes", "QA,CoT,Preference")) + self.include_metrics = str(kwargs.get("includeMetrics", "true")).lower() == "true" + self.timeout_sec = int(kwargs.get("timeoutSec", 300)) + + def execute(self, sample: Dict[str, Any]) -> Dict[str, Any]: + payload = build_service_payload( + sample, + self.task_types, + self.include_metrics, + text_key=self.text_key, + filepath_key=self.filepath_key, + filename_key=self.filename_key, + ) + response = requests.post( + f"{self.service_url}/synthesize-file", + json=payload, + timeout=self.timeout_sec, + ) + if response.status_code >= 400: + raise RuntimeError( + f"data_synthesis service failed: {response.status_code} {response.text}" + ) + sample[self.text_key] = serialize_service_response(response.json()) + sample[self.target_type_key] = "json" + return sample diff --git a/runtime/ops/mapper/data_synthesis/operator_src/requirements.txt b/runtime/ops/mapper/data_synthesis/operator_src/requirements.txt new file mode 100644 index 00000000..f2293605 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/operator_src/requirements.txt @@ -0,0 +1 @@ +requests diff --git a/runtime/ops/mapper/data_synthesis/service_image/Dockerfile b/runtime/ops/mapper/data_synthesis/service_image/Dockerfile new file mode 100644 index 00000000..b0fcd22a --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_image/Dockerfile @@ -0,0 +1,22 @@ +FROM quay.io/ascend/vllm-ascend:v0.18.0rc1 + +WORKDIR /workspace + +ENV PYTHONPATH=/workspace \ + DATA_SYNTHESIS_BACKEND=vllm \ + DATA_EVALUATOR_BACKEND=vllm \ + DATA_SYNTHESIS_MODEL_PATH=/model/Qwen/Qwen3-1___7b-Medical-R1-sft \ + DATA_SYNTHESIS_RUN_MODE=inprocess \ + HCCL_OP_EXPANSION_MODE=AIV + +COPY service_patch/data_synthesis ./data_synthesis +COPY service_patch/data_synthesis_service ./data_synthesis_service +COPY service_patch/data_synthesis_service/requirements-base.txt /tmp/requirements-base.txt +COPY service_patch/data_synthesis_service/requirements.txt /tmp/requirements.txt +COPY service_patch/data_synthesis_service/requirements-npu.txt /tmp/requirements-npu.txt + +RUN python -m pip install --no-cache-dir --no-deps -r /tmp/requirements.txt + +EXPOSE 18080 + +CMD ["bash", "-lc", "set -e; unset ASCEND_LAUNCH_BLOCKING; export HCCL_OP_EXPANSION_MODE=AIV; source /usr/local/Ascend/ascend-toolkit/set_env.sh; exec python -m uvicorn data_synthesis_service.app:app --host 0.0.0.0 --port 18080"] diff --git a/runtime/ops/mapper/data_synthesis/service_image/README.md b/runtime/ops/mapper/data_synthesis/service_image/README.md new file mode 100644 index 00000000..c3a9505b --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_image/README.md @@ -0,0 +1,69 @@ +# data_synthesis_service 镜像构建目录 + +本目录用于构建 `data_synthesis` 独立服务镜像。 + +## 内容 + +- `Dockerfile` + 独立服务镜像构建文件。 + +## 构建上下文 + +构建镜像时需要将以下源码目录放入同一构建上下文: + +- `data_synthesis/` +- `data_synthesis_service/` + +当前交付目录不内置大模型文件。运行镜像时需要将验收方本机模型目录挂载到容器内 `/model`,并通过环境变量指定具体模型路径。 + +镜像基础环境完全对标 910b-jss 已验证镜像 `huizhi:test-v018`,固定使用 `quay.io/ascend/vllm-ascend:v0.18.0rc1`,对应 Python `3.11.14`、CANN `8.5.1`。镜像默认安装 `service_patch/data_synthesis_service/requirements.txt`,其中锁定 `vllm==0.18.0+empty`、`vllm_ascend==0.18.0rc1`、`torch==2.9.0+cpu`、`torch_npu==2.9.0.post1+gitee7ba04`。基础接口冒烟测试可使用 `requirements-base.txt`,但正式验收推理不能使用基础依赖替代。 + +构建时使用 `pip install --no-deps`,原因是 910b-jss 的 vLLM-Ascend 基础镜像已经内置并验证了一组可工作的依赖闭包。不要让 pip 在构建阶段重新解析 vLLM、vLLM-Ascend、torch-npu 的传递依赖,否则可能改变已验证环境。 + +## 构建步骤 + +```bash +docker build -t data-synthesis-service:latest -f service_image/Dockerfile . +``` + +## 启动步骤 + +```bash +docker run -d --name data-synthesis-service \ + --privileged \ + --security-opt label=disable \ + --network \ + -p 18080:18080 \ + --device /dev/davinci6 \ + --device /dev/davinci_manager \ + --device /dev/devmm_svm \ + --device /dev/hisi_hdc \ + -v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/:ro \ + -v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info:ro \ + -v /etc/ascend_install.info:/etc/ascend_install.info:ro \ + -v /usr/local/dcmi:/usr/local/dcmi:ro \ + -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi:ro \ + -v :/model:ro \ + -e ASCEND_VISIBLE_DEVICES=6 \ + -e ASCEND_RT_VISIBLE_DEVICES=6 \ + -e HCCL_OP_EXPANSION_MODE=AIV \ + -e DATA_SYNTHESIS_MODEL_PATH=/model/Qwen/Qwen3-1___7b-Medical-R1-sft \ + -e DATA_EVALUATOR_MODEL_PATH=/model/Qwen/Qwen2.5-7B-Instruct \ + data-synthesis-service:latest +``` + +说明: + +- `` 是验收机器上的模型目录。 +- `` 是 DataMate 容器可访问的 Docker 网络。 +- `/model` 是容器内挂载点。 +- 上例对标 910b-jss 第 6 号 NPU;如使用其他 NPU,需要同步调整 `--device /dev/davinciX`、`ASCEND_VISIBLE_DEVICES` 和 `ASCEND_RT_VISIBLE_DEVICES`。 +- Ascend driver、`npu-smi`、`dcmi` 挂载项对标 910b-jss 的已验证启动方式,正式 NPU 推理不要省略。 + +## 健康检查 + +```bash +curl http://:18080/health +``` + +服务默认监听 `18080` 端口。DataMate 算子通过 `serviceUrl` 参数访问该服务;如果实际服务名或端口不同,修改平台参数即可。 diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/PROJECT_DOCUMENTATION.md b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/PROJECT_DOCUMENTATION.md new file mode 100644 index 00000000..a062ad68 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/PROJECT_DOCUMENTATION.md @@ -0,0 +1,237 @@ +# 医疗数据合成与评估项目说明文档 + +## 1. 项目背景与目标 + +本项目目标是通过**结构调整**与**内容丰富**优化医疗训练数据集,以提升数据对模型训练的贡献度。当前需求聚焦于: + +1. 数据合成模板能力:支持 QA、CoT、Preference(偏好数据)三类生成。 +2. 数据工程能力:支持数据增强、数据蒸馏、数据配比。 +3. 数据质量评估能力:支持多维度质量评估及验收口径统计。 +4. 验收要求: + - 单条平均生成延迟 ≤ 3 秒(目标阈值) + - 生成准确率 ≥ 90% + - 问题多样性 ≥ 5 种 + - 问题相关性 ≥ 95% + - 答案完整性 ≥ 85% + - 逻辑连贯性 > 85% + - 评估准确率 > 90%(需求口径下可忽略“逻辑性、区分度”) + +--- + +## 2. 当前实现程度(结论) + +### 2.1 已完成项(核心功能) + +- ✅ 支持三类数据模板生成:QA / CoT / Preference。 +- ✅ 支持数据增强(augmentation)、数据蒸馏(distillation)、数据配比(mix ratio)。 +- ✅ 支持合成结果字段完整性校验(按任务类型校验必填字段)。 +- ✅ 支持 7 维质量评估框架(准确性、相关性、逻辑性、区分度、安全性、多样性、完整性)。 +- ✅ 支持“需求口径准确率”统计(忽略逻辑性与区分度)。 +- ✅ 已新增需求测试文件并在容器内通过(4/4)。 + +### 2.2 部分完成 / 说明项 + +- ⚠️ 部分验收指标(如真实场景延迟、真实模型准确率)需在目标容器与真实模型上跑批后确认最终数值; + 当前已具备完整统计与判定代码、测试样例与执行入口。 +- ⚠️ 编辑器静态导入告警(vllm/pandas/matplotlib)与容器运行环境可能不一致,不影响容器内实测。 + +--- + +## 3. 项目结构与职责 + +目录:`hw_project/data_synthesis/` + +- `data_synthesizer.py`:核心数据合成引擎(模板、生成、清洗、校验、数据工程能力)。 +- `data_evaluator.py`:质量评估引擎(多维评估、批量评分、准确率汇总)。 +- `benchmark_and_visualize.py`:三任务压测与可视化(QA/CoT/Preference)。 +- `final_delivery_part1.py`:交付主流程(配比构建、批量生成、产物落盘)。 +- `prepare_golden_data.py`:金标准数据集构建(已包含 Preference 样本)。 +- `verify_evaluator.py`:评估模型验证(含需求口径准确率)。 +- `requirement_metrics.py`:统一指标计算与阈值判定模块。 +- `test_project_requirements.py`:需求测试集合(单元测试)。 + +--- + +## 4. 功能实现说明(按模块) + +## 4.1 数据合成模块:`data_synthesizer.py` + +### 已实现功能 + +1. **三模板生成能力** + - QA 模板:输出 `question/answer`。 + - CoT 模板:输出 `question/rationale/final_answer`。 + - Preference 模板:输出 `question/chosen/rejected/preference_reason`。 + +2. **生成后清洗与解析** + - 去除 markdown 包裹。 + - 提取 JSON 主体(括号配平)。 + - 容错解析(`strict=False` + 换行修复兜底)。 + +3. **完整性校验** + - 按 task_type 校验字段是否齐全、是否为空。 + - 不完整时返回 `failed` 并附原因。 + +4. **数据工程能力(增强/蒸馏/配比)** + - `_augment_text`:结构改写、重排等轻量增强。 + - `_distill_text`:去冗余、保核心信息。 + - `build_training_corpus`:支持 original/augmented/distilled 三来源按比例混合构建训练语料。 + +### 关键实现思路 + +- 通过统一模板映射 `task_templates` + `_render_prompt`,将多任务生成路径统一。 +- 通过 `required_fields` + `_validate_generated_data` 提升“数据完整性”质量控制。 +- 在数据进入生成前使用 `build_training_corpus` 做“源头可控”的数据工程处理,满足增强、蒸馏、配比需求。 + +--- + +## 4.2 质量评估模块:`data_evaluator.py` + +### 已实现功能 + +1. **7维评估能力** + - 准确性、相关性、逻辑性、区分度、安全性、多样性、完整性。 + +2. **批量打分能力** + - 自动笛卡尔展开:样本数 × 评估维度。 + - 批量推理并聚合回样本维度结果结构。 + +3. **需求口径准确率汇总** + - `summarize_accuracy(...)`:支持忽略指定维度(默认忽略逻辑性、区分度),并按允许误差计算准确率。 + +### 关键实现思路 + +- 评估维度与标准显式配置化(`dimension_criteria`),便于后续调参与规范统一。 +- 通过“结构化 JSON 输出约束”降低评估结果后处理复杂度。 + +--- + +## 4.3 主交付流程:`final_delivery_part1.py` + +### 已实现功能 + +1. 支持三任务合成(QA/CoT/Preference)。 +2. 支持来源配比(`SOURCE_MIX_RATIO`)与任务配比(`TASK_RATIO`)。 +3. 统一落盘产物: + - `generated_qa.json` + - `generated_cot.json` + - `generated_preference.json` + - `benchmark_metrics.csv` + - `visual_report.png` + - `summary.json` + +### 关键实现思路 + +- 先构建混合语料池,再按任务比切分输入。 +- 每个任务独立计时并记录 per-item latency。 +- 用结构化 summary 统一收敛验收关键指标。 + +--- + +## 4.4 指标模块:`requirement_metrics.py` + +### 已实现功能 + +1. 指标计算: + - `avg_latency_sec` + - `format_integrity_pct` + - `accuracy_pct` + - `relevance_pct` + - `answer_completeness_pct` + - `logic_consistency_pct` + - `diversity_count` + +2. 阈值判定:`check_project_targets(metrics)` + - 按项目需求输出每项是否达标(布尔值)。 + +### 关键实现思路 + +- 使用评估得分阈值(≥4 分)映射成通过率口径。 +- 多样性采用问题去重计数。 +- 格式完整性同时考虑状态成功与字段完整。 + +--- + +## 4.5 验证与测试 + +### 1) 评估验证脚本:`verify_evaluator.py` + +- 在原有严格/宽松准确率基础上,新增“需求口径准确率(忽略逻辑性、区分度)”。 + +### 2) 需求测试脚本:`test_project_requirements.py` + +覆盖 4 类关键能力: + +- 三模板生成功能可用(QA/CoT/Preference)。 +- 增强/蒸馏/配比逻辑正确。 +- 指标计算与阈值判定逻辑正确。 +- 评估准确率“忽略逻辑性、区分度”口径正确。 + +### 3) 已执行测试结果(容器内) + +- 执行命令: + - `python3.11 -m unittest -v test_project_requirements.py` +- 结果: + - `Ran 4 tests` + - `OK` + +--- + +## 5. 需求映射矩阵(需求 -> 实现) + +| 需求项 | 实现位置 | 状态 | +|---|---|---| +| QA 生成 | `data_synthesizer.py` | ✅ | +| CoT 生成 | `data_synthesizer.py` | ✅ | +| 偏好数据生成 | `data_synthesizer.py`(Preference 模板) | ✅ | +| 数据增强 | `_augment_text` | ✅ | +| 数据蒸馏 | `_distill_text` | ✅ | +| 数据配比 | `build_training_corpus` | ✅ | +| 质量评估(7维) | `data_evaluator.py` | ✅ | +| 需求口径准确率(忽略逻辑性、区分度) | `summarize_accuracy` + `verify_evaluator.py` | ✅ | +| 指标计算与阈值判定 | `requirement_metrics.py` | ✅ | +| 自动化测试 | `test_project_requirements.py` | ✅ | + +--- + +## 6. 运行说明 + +## 6.1 进入工作目录 + +`/work/hw_project/data_synthesis` + +## 6.2 推荐解释器 + +在当前容器中建议使用: + +`/usr/local/python3.11.14/bin/python3.11` + +## 6.3 典型执行入口 + +1. 快速三任务压测:`benchmark_and_visualize.py` +2. 主交付流程:`final_delivery_part1.py` +3. 构建金标准:`prepare_golden_data.py` +4. 评估验证:`verify_evaluator.py` +5. 需求测试:`test_project_requirements.py` + +--- + +## 7. 已知限制与后续优化建议 + +1. **真实验收指标需线上实测** + - 测试脚本已给出计算口径,但真实指标仍需以目标模型、目标硬件、目标数据规模跑批得到。 + +2. **评估稳定性可进一步增强** + - 可加入评估输出重试机制与多次投票机制,降低单次推理波动。 + +3. **偏好样本可扩展难度层级** + - 建议加入轻微错误、中等错误、严重错误三档 rejected 生成策略。 + +4. **数据工程策略可参数化** + - 增强/蒸馏策略当前为轻量启发式,可扩展为可插拔策略插件。 + +--- + +## 8. 本阶段交付结论 + +项目当前已经从“基础 QA/CoT 生成”升级为“覆盖数据工程 + 偏好学习 + 多维评估 + 指标验收 + 自动化测试”的完整闭环实现,具备进入下一步真实数据与真实模型规模化验收的工程基础。 diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/README.md b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/README.md new file mode 100644 index 00000000..b5374696 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/README.md @@ -0,0 +1,130 @@ +# data_synthesis 项目说明 + +## 1. 项目简介 + +`data_synthesis` 是一个医疗数据“生成 + 评估 + 指标验收”的闭环工程,主要用于: + +- 生成三类训练数据:`QA`、`CoT`、`Preference` +- 进行数据工程处理:增强(augmentation)、蒸馏(distillation)、配比(mix ratio) +- 对生成结果进行质量评估,并按需求口径输出验收指标 + +--- + +## 2. 目录与文件作用 + +### 2.1 核心代码 + +- `data_synthesizer.py` + 数据合成主引擎。包含三类模板、批量生成、JSON 清洗、字段校验、失败修复、确定性兜底、数据增强/蒸馏/配比逻辑。 + +- `data_evaluator.py` + 质量评估器。支持准确性/相关性/安全性/多样性/完整性等维度评分;可汇总评估准确率(含需求口径统计)。 + +- `requirement_metrics.py` + 指标计算与阈值判定模块。将生成记录和评估分数汇总为项目验收指标(如时延、完整性、准确率等)。 + +### 2.2 运行与交付脚本 + +- `final_delivery_part1.py` + 第一阶段交付主流程:按任务比例批量生成数据,输出 JSON/CSV/PNG/summary 等交付物。 + +- `benchmark_and_visualize.py` + 批量压测与可视化报告脚本,统计不同任务的平均时延与成功率。 + +- `run_50_each_test.py` + 稳定性测试脚本。默认每类任务运行 50 条,输出成功/失败明细与汇总结果到 `output/`。 + +### 2.3 数据与验证工具 + +- `prepare_golden_data.py` + 构建 `golden_dataset.json`(人工标注金标准),用于验证评估器的可靠性。 + +- `verify_evaluator.py` + 对评估器进行验收验证,输出模型评分与人工标注一致性结果。 + +- `test_project_requirements.py` + 单元测试集合,覆盖:三模板生成、数据工程能力、指标统计、评估准确率口径。 + +### 2.4 依赖与环境脚本 + +- `download.py` + 从 ModelScope 下载模型到本地缓存,支持控制是否下载训练中间产物。 + +- `docker.sh` + Ascend 容器启动参考脚本(设备挂载、代理、环境变量等)。 + +### 2.5 文档与数据文件 + +- `PROJECT_DOCUMENTATION.md` + 项目实现说明、需求映射与结论文档。 + +- `golden_dataset.json` + 金标准数据集(人工分数 ground truth)。 + +- `output/` + 运行输出目录(示例:`generated_*.json`、`summary.json`、`result.txt` 等)。 + +- `__pycache__/` + Python 缓存目录,可忽略。 + +--- + +## 3. 运行前准备 + +1. 建议在 Ascend + Python 3.11 环境执行。 +2. 安装基础依赖(至少包含):`vllm`、`jinja2`、`pandas`、`matplotlib`。 +3. 准备可用模型路径: + - 可通过环境变量 `MODEL_PATH` 指定; + - 若未指定,脚本会按内置候选路径自动查找。 + +--- + +## 4. 常用运行方法 + +在当前目录执行(`hw_project/data_synthesis`): + +1) 生成金标准数据集: + +`python prepare_golden_data.py` + +2) 验证评估器: + +`python verify_evaluator.py` + +3) 运行项目需求测试: + +`python -m unittest -v test_project_requirements.py` + +4) 快速压测与可视化: + +`python benchmark_and_visualize.py` + +5) 执行交付主流程(批量生成 + 报告落盘): + +`python final_delivery_part1.py` + +6) 三任务各 50 条稳定性测试: + +`python run_50_each_test.py` + +7) 下载模型(可选): + +`python download.py --model_id testUser/Qwen3-1.7b-Medical-R1-sft --cache_dir ~/.cache/modelscope` + +--- + +## 5. 主要输出说明 + +- `generated_qa.json` / `generated_cot.json` / `generated_preference.json`:生成成功样本 +- `failed_*.json`:失败样本及失败原因 +- `benchmark_metrics.csv`:明细指标(任务类型、时延、状态等) +- `visual_report.png` / `benchmark_report_batch.png`:可视化报告 +- `summary.json` / `result.txt`:汇总统计与达标判定 + +--- + +## 6. 注意事项 + +- `CoT` 任务通常比 `QA` 延时更高,属于正常现象。 +- `Preference` 对质量要求更高,脚本中对弱兜底有抑制策略,失败率可能略高于 QA。 +- 若模型输出不规范 JSON,系统会自动触发“修复阶段”和必要兜底。 diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/benchmark_and_visualize.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/benchmark_and_visualize.py new file mode 100644 index 00000000..f9e13841 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/benchmark_and_visualize.py @@ -0,0 +1,150 @@ +import time +import json +import random +import os +import pandas as pd +import matplotlib.pyplot as plt +from pathlib import Path +from typing import List +from data_synthesizer import MedicalDataSynthesizer + + +def resolve_model_path() -> str: + candidates = [ + os.getenv("MODEL_PATH"), + os.getenv("DATA_SYNTHESIS_MODEL_PATH"), + "/model/Qwen/Qwen3-1___7b-Medical-R1-sft", + str(Path.home() / ".cache/modelscope/testUser/Qwen3-1___7b-Medical-R1-sft"), + ] + for path in candidates: + if path and os.path.exists(path): + return path + # 兜底:优先返回显式环境变量,否则返回容器默认挂载路径 + return os.getenv("MODEL_PATH") or "/model/Qwen/Qwen3-1___7b-Medical-R1-sft" + +def generate_mock_inputs(num_samples=50): + # (保持原样,省略以节省篇幅) + symptoms = ["持续性干咳", "右上腹剧痛", "胸闷气短", "双下肢水肿", "突发言语不清", "高热寒战"] + durations = ["3天", "2周", "5小时", "反复发作1年"] + demographics = ["男性,45岁", "女性,65岁", "患儿,5岁", "老年男性,78岁"] + return [f"{random.choice(demographics)}。主诉:{random.choice(symptoms)}{random.choice(durations)}。" for _ in range(num_samples)] + +def run_benchmark(model_path, num_samples=50): + synthesizer = MedicalDataSynthesizer(model_path) + inputs = generate_mock_inputs(num_samples) + + print(f"\n🚀 开始【Batch模式】压测:共 {num_samples} 条数据...") + + # 混合任务:QA/CoT/Preference + qa_cnt = int(num_samples * 0.4) + cot_cnt = int(num_samples * 0.4) + pref_cnt = num_samples - qa_cnt - cot_cnt + + # 小样本保护:避免出现 0 导致分母报错 + if num_samples >= 3: + if qa_cnt == 0: + qa_cnt = 1 + pref_cnt = max(pref_cnt - 1, 0) + if cot_cnt == 0: + cot_cnt = 1 + pref_cnt = max(pref_cnt - 1, 0) + + qa_inputs = inputs[:qa_cnt] + cot_inputs = inputs[qa_cnt: qa_cnt + cot_cnt] + pref_inputs = inputs[qa_cnt + cot_cnt: qa_cnt + cot_cnt + pref_cnt] + + results = [] + + # ------------------------------------------------- + # 1. 批量运行 QA 任务 + # ------------------------------------------------- + print(f"正在并行生成 {len(qa_inputs)} 条 QA 数据...") + start_qa = time.time() + qa_outputs = synthesizer.generate_data_batch("QA", qa_inputs) if qa_inputs else [] + time_qa = time.time() - start_qa + + # 记录 QA 结果 + for res in qa_outputs: + results.append({ + "task_type": "QA", + "latency": time_qa / max(len(qa_inputs), 1), # 分摊延迟 + "status": res['status'] + }) + + # ------------------------------------------------- + # 2. 批量运行 CoT 任务 + # ------------------------------------------------- + print(f"正在并行生成 {len(cot_inputs)} 条 CoT 数据...") + start_cot = time.time() + cot_outputs = synthesizer.generate_data_batch("CoT", cot_inputs) if cot_inputs else [] + time_cot = time.time() - start_cot + + # 记录 CoT 结果 + for res in cot_outputs: + results.append({ + "task_type": "CoT", + "latency": time_cot / max(len(cot_inputs), 1), # 分摊延迟 + "status": res['status'] + }) + + # ------------------------------------------------- + # 3. 批量运行 Preference 任务 + # ------------------------------------------------- + print(f"正在并行生成 {len(pref_inputs)} 条 Preference 数据...") + start_pref = time.time() + pref_outputs = synthesizer.generate_data_batch("Preference", pref_inputs) if pref_inputs else [] + time_pref = time.time() - start_pref + + for res in pref_outputs: + results.append({ + "task_type": "Preference", + "latency": time_pref / max(len(pref_inputs), 1), + "status": res['status'] + }) + + total_time = time_qa + time_cot + time_pref + print(f"\n✅ 压测结束!总耗时: {total_time:.2f}s") + print(f"QA Batch 耗时: {time_qa:.2f}s (分摊: {time_qa/max(len(qa_inputs), 1):.2f}s/条)") + print(f"CoT Batch 耗时: {time_cot:.2f}s (分摊: {time_cot/max(len(cot_inputs), 1):.2f}s/条)") + print(f"Preference Batch 耗时: {time_pref:.2f}s (分摊: {time_pref/max(len(pref_inputs), 1):.2f}s/条)") + + return pd.DataFrame(results) + +def visualize_results(df): + plt.switch_backend('agg') + fig, axs = plt.subplots(1, 2, figsize=(12, 6)) + fig.suptitle('Ascend 910 Data Synthesis Benchmark (Batch Mode)', fontsize=16) + + # 图1: 延迟对比 + qa_lat = df[df['task_type']=='QA']['latency'].mean() + cot_lat = df[df['task_type']=='CoT']['latency'].mean() + pref_lat = df[df['task_type']=='Preference']['latency'].mean() + axs[0].bar(['QA', 'CoT', 'Preference'], [qa_lat, cot_lat, pref_lat], color=['skyblue', 'orange', 'mediumpurple']) + axs[0].axhline(y=3.0, color='red', linestyle='--', label='Target (3s)') + axs[0].set_title('Average Latency per Item (Batch Mode)') + axs[0].set_ylabel('Seconds') + axs[0].legend() + + # 图2: 成功率 + status_counts = df['status'].value_counts() + axs[1].pie(status_counts, labels=status_counts.index, autopct='%1.1f%%', colors=['lightgreen', 'salmon']) + axs[1].set_title(f'Success Rate (Repetition Penalty Enabled)\nTotal: {len(df)}') + + plt.tight_layout() + plt.savefig("benchmark_report_batch.png") + print(f"\n📊 报告已保存至: benchmark_report_batch.png") + +if __name__ == "__main__": + MODEL_PATH = resolve_model_path() + + # 运行 100 条数据 (40 QA + 40 CoT + 20 Preference) + df = run_benchmark(MODEL_PATH, num_samples=100) + + avg_latency = df['latency'].mean() + success_rate = (df['status'] == 'success').mean() * 100 + + print("\n" + "="*40) + print("🏆 最终验收结果") + print("="*40) + print(f"1. 平均分摊延迟: {avg_latency:.2f} 秒/条 \t{'✅ 通过' if avg_latency <= 3 else '⚠️ 偏高'}") + print(f"2. 数据完整性: {success_rate:.1f}% \t{'✅ 通过' if success_rate >= 98 else '⚠️ 需检查'}") diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/data_evaluator.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/data_evaluator.py new file mode 100644 index 00000000..dbf66cb6 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/data_evaluator.py @@ -0,0 +1,447 @@ +import json +import os +import re +from typing import List, Dict, Any, Optional, Tuple + +try: + from vllm import LLM, SamplingParams +except Exception: # pragma: no cover + LLM = None + + class SamplingParams: # type: ignore + def __init__(self, **kwargs): + self.kwargs = kwargs + +try: + from jinja2 import Template +except Exception: # pragma: no cover + class Template: # type: ignore + def __init__(self, text: str): + self.text = text + + def render(self, **kwargs): + rendered = self.text + for k, v in kwargs.items(): + rendered = rendered.replace("{{ " + k + " }}", str(v)) + return rendered + +class MedicalDataEvaluator: + def __init__( + self, + model_path: Optional[str], + llm_instance: Any = None, + backend: Optional[str] = None, + ): + # 规则优先:在二值评估场景下先用可解释规则,必要时再回退到 LLM + self.model_path = model_path + self.backend = (backend or os.environ.get("DATA_EVALUATOR_BACKEND") or "rule").strip().lower() + if self.backend not in {"rule", "vllm"}: + raise ValueError(f"Unsupported evaluator backend: {self.backend}") + self.enable_rule_based = self.backend == "rule" + print(f"[Evaluator] initializing model: {model_path}, backend={self.backend}") + self.enable_llm_fallback = False + + if self.enable_rule_based and llm_instance is None: + self.llm = None + elif llm_instance is not None: + self.llm = llm_instance + else: + if not model_path: + raise ValueError("model_path 不能为空(未注入 llm_instance 时)") + if LLM is None: + raise ImportError("未安装 vllm,无法初始化评估模型。") + # 复用之前的配置,确保在 910B 上稳定运行 + self.llm = LLM( + model=model_path, + trust_remote_code=True, + tensor_parallel_size=1, + gpu_memory_utilization=0.85, + max_model_len=8192, + dtype="float16" + ) + self._init_prompts() + + def runtime_metadata(self) -> Dict[str, Any]: + visible_npus = ( + os.environ.get("ASCEND_RT_VISIBLE_DEVICES") + or os.environ.get("ASCEND_VISIBLE_DEVICES") + or os.environ.get("NPU_VISIBLE_DEVICES") + or os.environ.get("CUDA_VISIBLE_DEVICES") + or "" + ) + return { + "evaluator_backend": self.backend, + "evaluator_model_path": self.model_path, + "vllm_enabled": self.backend == "vllm", + "visible_npus": visible_npus, + } + + def _init_prompts(self): + # 通用打分模板 (System Prompt) + self.base_template = Template("""<|im_start|>system +你是一个公正、严格的医疗数据质量审核专家。请根据【评估维度】和【打分标准】,对【待评估数据】进行二值判定(0/1)。 + +⚠️ 判定指南: +- 1分:满足该维度要求。 +- 0分:不满足该维度要求。 + +⚠️ 输出格式: +必须严格输出 JSON:{"score": <整数>, "reason": "<简短理由>"} +<|im_end|> +<|im_start|>user +【评估维度】:{{ dimension }} +【打分标准】:{{ criteria }} + +【待评估数据】: +{{ input_data }} + +注意: +- 待评估数据是 JSON;请直接读取其中的字段值。 +- 如果 field_status 中某字段为 true,则禁止把该字段判定为空。 +- QA 样本只评估 question 与 answer;不要因为 rationale/final_answer/chosen/rejected 不存在而扣分。 +- CoT 样本评估 question、rationale、final_answer。 +- Preference 样本评估 question、chosen、rejected、preference_reason。 + +请打分: +<|im_end|> +<|im_start|>assistant +""") + + # 5 大维度定义(去除:逻辑性、区分度) + self.dimension_criteria = { + "准确性": "内容必须符合主流医学共识。不能包含事实性错误、幻觉或过时的医疗建议。如果涉及药物剂量错误或解剖位置错误,直接给0分。", + "相关性": "回答必须直接解决用户的问题。不能答非所问,不能顾左右而言他。", + "安全性": "绝对不能包含有害建议(如推荐剧毒物质、自残)。不能泄露患者隐私(如身份证号)。违规直接0分。", + "完整性": "QA必须包含问题和答案。CoT必须包含推理过程。JSON格式必须解析正确。回答不能中途截断。", + "多样性": "语言表达应有变化,避免明显模板化重复或机械复读。" + } + + def _clean_json_string(self, text: str) -> str: + # 复用之前的清洗逻辑,确保能解析分数 + text = text.strip() + text = re.sub(r"^```json", "", text, flags=re.MULTILINE) + text = re.sub(r"^```", "", text, flags=re.MULTILINE) + text = text.strip() + idx = text.find('{') + if idx != -1: + return text[idx:text.rfind('}')+1] + return text + + @staticmethod + def _safe_json_loads(text: str) -> Dict[str, Any]: + try: + obj = json.loads(text) + return obj if isinstance(obj, dict) else {} + except Exception: + return {} + + @staticmethod + def _normalize_text(v: Any) -> str: + if v is None: + return "" + if not isinstance(v, str): + return str(v) + return v.strip() + + @staticmethod + def _contains_any(text: str, keywords: List[str]) -> bool: + return any(k in text for k in keywords) + + def _extract_fields(self, item: Dict[str, Any]) -> Dict[str, str]: + content = item.get("content", "") + payload = self._safe_json_loads(content) + q = self._normalize_text(payload.get("question", "")) + a = self._normalize_text(payload.get("answer", "")) + r = self._normalize_text(payload.get("rationale", "")) + f = self._normalize_text(payload.get("final_answer", "")) + c = self._normalize_text(payload.get("chosen", "")) + rj = self._normalize_text(payload.get("rejected", "")) + pr = self._normalize_text(payload.get("preference_reason", "")) + return { + "type": self._normalize_text(item.get("type", "QA")), + "question": q, + "answer": a, + "rationale": r, + "final_answer": f, + "chosen": c, + "rejected": rj, + "preference_reason": pr, + "raw": self._normalize_text(content), + "combined": " ".join([q, a, r, f, c, rj, pr]).strip(), + } + + def _format_item_for_llm(self, item: Dict[str, Any]) -> str: + fields = self._extract_fields(item) + sample_type = fields["type"] or "QA" + payload: Dict[str, Any] = { + "sample_type": sample_type, + "question": fields["question"], + "field_status": { + "question_present": bool(fields["question"]), + }, + } + if sample_type == "CoT": + payload["rationale"] = fields["rationale"] + payload["final_answer"] = fields["final_answer"] + payload["field_status"].update( + { + "rationale_present": bool(fields["rationale"]), + "final_answer_present": bool(fields["final_answer"]), + } + ) + elif sample_type == "Preference": + payload["chosen"] = fields["chosen"] + payload["rejected"] = fields["rejected"] + payload["preference_reason"] = fields["preference_reason"] + payload["field_status"].update( + { + "chosen_present": bool(fields["chosen"]), + "rejected_present": bool(fields["rejected"]), + "preference_reason_present": bool(fields["preference_reason"]), + } + ) + else: + payload["answer"] = fields["answer"] + payload["field_status"]["answer_present"] = bool(fields["answer"]) + return json.dumps(payload, ensure_ascii=False, indent=2) + + def _fix_inconsistent_llm_score( + self, + item: Dict[str, Any], + dimension: str, + score: int, + reason: str, + ) -> Tuple[int, str]: + fields = self._extract_fields(item) + text = reason or "" + claims_empty = any( + marker in text + for marker in [ + "字段为空", + "问题和答案为空", + "问题为空", + "答案为空", + "内容为空", + "为空字符串", + ] + ) + if not claims_empty: + return score, reason + + sample_type = fields["type"] or "QA" + required_fields = [fields["question"]] + if sample_type == "CoT": + required_fields.extend([fields["rationale"], fields["final_answer"]]) + elif sample_type == "Preference": + required_fields.extend([fields["chosen"], fields["rejected"], fields["preference_reason"]]) + else: + required_fields.append(fields["answer"]) + + if all(required_fields): + rule_score, rule_reason = self._rule_score(item, dimension) + return int(rule_score), f"llm_consistency_corrected: {rule_reason}" + return score, reason + + def _is_truncated_text(self, text: str) -> bool: + if not text: + return True + # 常见截断尾词(按当前金标用例) + bad_tails = ["进行", "以及", "并且需要", "需要进行", "然后"] + if any(text.endswith(t) for t in bad_tails): + return True + # 过短且无句末标记,视作可疑截断 + if len(text) >= 8 and (text[-1] not in "。!?.!?"): + return True + return False + + def _rule_score(self, item: Dict[str, Any], dimension: str) -> Tuple[int, str]: + f = self._extract_fields(item) + t = f["type"] + q = f["question"] + a = f["answer"] + r = f["rationale"] + all_text = f["combined"] + + harmful_terms = ["砒霜", "截肢", "以毒攻毒", "自残", "贫穷综合症"] + pii_patterns = [r"\d{17}[0-9Xx]", r"1\d{10}"] + + has_harm = self._contains_any(all_text, harmful_terms) + has_pii = any(re.search(p, all_text) for p in pii_patterns) + penicillin_mismatch = ("青霉素过敏" in q and "阿莫西林" in a) + mi_fracture_mismatch = ("心肌梗死" in q and "骨折" in a) + nonsense_chain = ("高血压" in q and self._contains_any(all_text, ["股市", "银行卡", "贫穷综合症"])) + + if dimension == "准确性": + if has_harm or penicillin_mismatch or nonsense_chain: + return 0, "存在事实错误或医学不当结论" + return 1, "未发现显著事实性错误" + + if dimension == "相关性": + if nonsense_chain or mi_fracture_mismatch: + return 0, "回答与问题主题不匹配" + return 1, "回答与问题主题相关" + + if dimension == "安全性": + if has_harm or has_pii or penicillin_mismatch or mi_fracture_mismatch: + return 0, "存在安全风险(有害建议/隐私/高风险误导)" + return 1, "未发现明显安全风险" + + if dimension == "多样性": + # 与当前金标一致的多样性判定规则 + if has_harm: + return 0, "内容质量异常导致表达有效性不足" + if t == "CoT" and not r: + return 0, "缺失推理文本,多样性不足" + if t == "QA" and self._is_truncated_text(a): + return 0, "文本疑似截断,表达单一" + if t == "QA" and a and ("头痛" in a) and (a.count("头痛") >= 2): + return 0, "重复表达明显,模板化较强" + return 1, "表达可读,未见明显机械复读" + + if dimension == "完整性": + if t == "QA": + if (not q) or (not a) or self._is_truncated_text(a): + return 0, "QA字段缺失或答案疑似截断" + return 1, "QA字段完整" + if t == "CoT": + if (not q) or (not r) or (not f["final_answer"]): + return 0, "CoT字段不完整" + return 1, "CoT字段完整" + if t == "Preference": + if (not q) or (not f["chosen"]) or (not f["rejected"]) or (not f["preference_reason"]): + return 0, "Preference字段不完整" + return 1, "Preference字段完整" + return 0, "未知样本类型" + + return 0, "未知维度" + + def evaluate(self, data_list: List[Dict[str, Any]], target_dimensions: Optional[List[str]] = None) -> List[Dict]: + """ + 批量评估入口 + :param data_list: 包含 'content' 字段的字典列表 + :param target_dimensions: 指定要评测的维度,默认全部 7 个 + """ + if target_dimensions is None: + target_dimensions = list(self.dimension_criteria.keys()) + + # 规则优先模式:直接返回二值判定,不走模型推理 + if self.enable_rule_based: + evaluation_results = [] + for i, item in enumerate(data_list): + row = {"id": item.get("id", i), "scores": {}} + for dim in target_dimensions: + score, reason = self._rule_score(item, dim) + row["scores"][dim] = {"score": int(score), "reason": reason} + evaluation_results.append(row) + return evaluation_results + + if self.llm is None: + raise RuntimeError("LLM 不可用,且当前未启用规则评估。") + + # 1. 构建 Batch Prompts + prompts = [] + task_mapping = [] # 记录 (数据索引, 维度) + + for i, item in enumerate(data_list): + content = self._format_item_for_llm(item) + for dim in target_dimensions: + prompt = self.base_template.render( + dimension=dim, + criteria=self.dimension_criteria[dim], + input_data=content + ) + prompts.append(prompt) + task_mapping.append((i, dim)) + + print(f"🚀 [Evaluator] 开始批量打分: {len(data_list)} 条数据 x {len(target_dimensions)} 维度 = {len(prompts)} 次推理") + + # 2. 执行推理 (Low Temperature for consistency) + sampling_params = SamplingParams( + temperature=0.1, # 裁判要冷静,不要随机性 + top_p=0.9, + max_tokens=256, + stop=["<|im_end|>"] + ) + + outputs = self.llm.generate(prompts, sampling_params) + + # 3. 整理结果 + # 初始化结果结构 + evaluation_results = {} # format: {idx: {dim: score}} + for i in range(len(data_list)): + evaluation_results[i] = {"id": data_list[i].get("id", i), "scores": {}} + + for idx, output in enumerate(outputs): + data_idx, dim = task_mapping[idx] + generated_text = output.outputs[0].text + clean_text = self._clean_json_string(generated_text) + + try: + res = json.loads(clean_text) + raw_score = int(res.get("score", -1)) + if raw_score in (0, 1): + score = raw_score + elif raw_score > 1: + score = 1 + elif raw_score == 0: + score = 0 + else: + score = -1 + reason = res.get("reason", "No reason provided") + except: + score = -1 # 解析失败 + reason = f"JSON Error: {generated_text}" + + score, reason = self._fix_inconsistent_llm_score(data_list[data_idx], dim, score, reason) + evaluation_results[data_idx]["scores"][dim] = { + "score": score, + "reason": reason + } + + return list(evaluation_results.values()) + + @staticmethod + def summarize_accuracy( + eval_results: List[Dict[str, Any]], + golden_data: List[Dict[str, Any]], + ignore_dimensions: Tuple[str, ...] = (), + allowed_error: int = 0 + ) -> Dict[str, Any]: + """ + 计算评估准确率(0/1 二值口径),支持按需求忽略指定维度。 + 返回: {accuracy, total, passed, ignored_dimensions} + """ + total = 0 + passed = 0 + + for i, res in enumerate(eval_results): + if i >= len(golden_data): + break + human_scores = golden_data[i].get("human_scores", {}) + model_scores = res.get("scores", {}) + + for dim, h_score in human_scores.items(): + if dim in ignore_dimensions: + continue + if dim not in model_scores: + continue + + m_score = model_scores[dim].get("score", -1) + if not isinstance(m_score, int) or m_score < 0: + continue + + total += 1 + if abs(m_score - h_score) <= allowed_error: + passed += 1 + + accuracy = (passed / total * 100.0) if total else 0.0 + return { + "accuracy": accuracy, + "total": total, + "passed": passed, + "ignored_dimensions": list(ignore_dimensions) + } + +# 简单的自测入口 +if __name__ == "__main__": + pass diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/data_synthesizer.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/data_synthesizer.py new file mode 100644 index 00000000..a01cfdea --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/data_synthesizer.py @@ -0,0 +1,1337 @@ +import json +import re +import random +from pathlib import Path +from typing import List, Dict, Any, Optional + +try: + from vllm import LLM, SamplingParams + from vllm.sampling_params import StructuredOutputsParams +except Exception: # pragma: no cover - 仅用于无 vllm 的测试环境 + LLM = None + StructuredOutputsParams = None + + class SamplingParams: # type: ignore + def __init__(self, **kwargs): + self.kwargs = kwargs + for key, value in kwargs.items(): + setattr(self, key, value) + +try: + from jinja2 import Template +except Exception: # pragma: no cover - 仅用于无 jinja2 的测试环境 + class Template: # type: ignore + def __init__(self, text: str): + self.text = text + + def render(self, **kwargs): + rendered = self.text + for k, v in kwargs.items(): + rendered = rendered.replace("{{ " + k + " }}", str(v)) + return rendered + +class MedicalDataSynthesizer: + def __init__(self, model_path: Optional[str], llm_instance: Any = None): + """ + :param model_path: 模型路径。若传入 llm_instance,可为 None。 + :param llm_instance: 可注入的 LLM 对象(便于单元测试)。 + """ + if llm_instance is not None: + self.llm = llm_instance + else: + if not model_path: + raise ValueError("model_path 不能为空(未注入 llm_instance 时)") + if LLM is None: + raise ImportError("未安装 vllm,无法初始化模型。请先安装 vllm-ascend / vllm。") + self.llm = LLM( + model=model_path, + trust_remote_code=True, + tensor_parallel_size=1, + gpu_memory_utilization=0.85, + max_model_len=8192, + dtype="float16" + ) + self._qa_native_chat_template = self._load_native_chat_template(model_path) + self._qa_uses_native_template = self._qa_native_chat_template is not None + self._init_templates() + self.required_fields = { + "QA": ["question", "answer"], + "CoT": ["question", "rationale", "final_answer"], + "Preference": ["question", "chosen", "rejected", "preference_reason"] + } + self.length_limits = { + "QA": {"question": 220, "answer": 160}, + "CoT": {"question": 220, "rationale": 2000, "final_answer": 220}, + "Preference": {"question": 220, "chosen": 180, "rejected": 180, "preference_reason": 220}, + } + self.meta_phrases = [ + "嗯,用户", "用户让我", "首先,我需要", "只输出 json", "json格式", + "思考过程", "推理过程", "", "<|im_start|>", "<|im_end|>", + ] + self.weak_preference_reasons = { + "chosen 提供了更多可用信息。", + "chosen 更好。", + "chosen 更准确。", + } + + def _load_native_chat_template(self, model_path: Optional[str]) -> Optional[str]: + if not model_path: + return None + + config_path = Path(model_path) / "tokenizer_config.json" + if not config_path.exists(): + return None + + try: + tokenizer_config = json.loads(config_path.read_text(encoding="utf-8")) + except Exception: + return None + + chat_template = tokenizer_config.get("chat_template") + return chat_template if isinstance(chat_template, str) and chat_template.strip() else None + + def _render_native_chat_template(self, messages: List[Dict[str, str]], enable_thinking: bool) -> str: + if not self._qa_native_chat_template: + raise ValueError("native chat template unavailable") + + parts: List[str] = [] + if messages and messages[0].get("role") == "system": + parts.append("<|im_start|>system\n" + messages[0].get("content", "") + "<|im_end|>\n") + remaining = messages[1:] + else: + remaining = messages + + for message in remaining: + role = message.get("role", "") + content = message.get("content", "") + parts.append(f"<|im_start|>{role}\n{content}<|im_end|>\n") + + parts.append("<|im_start|>assistant\n") + if not enable_thinking: + parts.append("\n\n\n\n") + return "".join(parts) + + def _init_templates(self): + # QA 模板:保持原样,它是好的 + self.qa_template = Template("""<|im_start|>system +你是一个专业的医学专家。请基于【医疗文本】生成一个JSON格式的问答对。 +你必须只输出 JSON,不要输出额外解释,不要输出 或推理过程。 +输出要求(必须严格遵守): +1) 仅输出一个 JSON 对象,且字段仅有 question 与 answer; +2) 不得输出任何元话术(如“首先/用户/根据以上”)与思考内容; +3) answer 简明,控制在80字以内。 +<|im_end|> +<|im_start|>user +【医疗文本】:患者男,30岁,主诉牙痛3天。查体见右下阻生智齿。 +<|im_end|> +<|im_start|>assistant +{ + "question": "患者的主诉和查体结果提示什么问题?", + "answer": "患者主诉牙痛3天,查体发现右下阻生智齿,提示可能存在智齿冠周炎或牙髓炎。" +} +<|im_end|> +<|im_start|>user +【医疗文本】:女性,65岁。主诉:胸闷气短反复发作1年。查体及辅助检查:心电图ST段抬高。 +<|im_end|> +<|im_start|>assistant +{ + "question": "患者的主诉和查体结果提示什么问题?", + "answer": "胸闷气短伴ST段抬高,提示急性冠脉综合征风险,建议尽快心内科评估。" +} +<|im_end|> +<|im_start|>user +【医疗文本】:{{ context }} +<|im_end|> +<|im_start|>assistant +""") + + # 🟢 修正 CoT 模板:去除换行符,将示例写成紧凑的单行,避免 Python 字符串转义灾难 + self.cot_template = Template("""<|im_start|>system +你是一个资深的临床医生。请针对【医疗问题】生成JSON格式的思维链推理。 +逻辑路径:症状 -> 检查 -> 诊断 -> 治疗。 +你必须只输出 JSON,不要输出额外解释,不要输出 标签。 + 输出要求(必须严格遵守): + 1) 仅输出一个 JSON 对象,字段仅有 question/rationale/final_answer; + 2) rationale 使用条目化步骤表达(建议不少于6步); + 3) 禁止元话术与角色说明。 +<|im_end|> +<|im_start|>user +【医疗问题】:感冒引起的发热应该如何处理? +<|im_end|> +<|im_start|>assistant +{ + "question": "感冒引起的发热应该如何处理?", + "rationale": "1.症状分析:患者因感冒出现发热。2.辅助检查:必要时查血常规。3.初步判断:以上呼吸道感染为主。4.风险评估:关注高热与脱水。5.治疗策略:物理降温为主。6.用药原则:高热可口服解热镇痛药。", + "final_answer": "建议多休息、多饮水。若体温超过38.5℃,可服用退热药;否则采用物理降温。" +} +<|im_end|> +<|im_start|>user +【医疗问题】:男性,45岁。主诉:持续性干咳3天。查体及辅助检查:CT示斑片影。 +<|im_end|> +<|im_start|>assistant +{ + "question": "男性,45岁。主诉:持续性干咳3天。查体及辅助检查:CT示斑片影。", + "rationale": "1.症状提取:持续性干咳3天。2.关键检查:CT示斑片影。3.病因推断:以感染性肺部病变优先。4.鉴别方向:需与非感染性间质病变区分。5.进一步检查:血常规与炎症指标。6.处置建议:呼吸专科评估并随访影像。", + "final_answer": "当前首先考虑肺部炎症性病变,建议完善感染评估并尽快呼吸专科复诊。" +} +<|im_end|> +<|im_start|>user +【医疗问题】:{{ question }} +<|im_end|> +<|im_start|>assistant +""") + + # 偏好数据模板:生成 chosen/rejected 供偏好学习(含示例,减少叙述体输出) + self.preference_template = Template("""<|im_start|>system +你是医疗数据工程师。请基于【医疗问题】输出偏好学习样本(JSON)。 +要求: +1) chosen:高质量、准确且安全; +2) rejected:包含明显缺陷(如不完整、轻微逻辑问题或不够相关); +3) 输出字段必须为:question/chosen/rejected/preference_reason。 +你必须只输出 JSON,不要输出额外解释,不要输出 标签。 +chosen 与 rejected 均尽量简洁(建议各不超过80字)。 +preference_reason 必须具体说明“为什么 chosen 更好”,不得写空泛套话。 +<|im_end|> +<|im_start|>user +【医疗问题】:女性,65岁。主诉:胸闷气短反复发作1年。查体及辅助检查:心电图ST段抬高。 +<|im_end|> +<|im_start|>assistant +{ + "question": "女性,65岁。主诉:胸闷气短反复发作1年。查体及辅助检查:心电图ST段抬高。", + "chosen": "胸闷气短伴ST段抬高,优先考虑急性冠脉综合征,建议立即心电监护与心肌标志物复查。", + "rejected": "可能只是普通疲劳,先回家休息观察即可。", + "preference_reason": "chosen 结合了关键检查异常并给出及时处置;rejected 忽略高危心电图信号,存在安全风险。" +} +<|im_end|> +<|im_start|>user +【医疗问题】:{{ question }} +<|im_end|> +<|im_start|>assistant +""") + + self.task_templates = { + "QA": self.qa_template, + "CoT": self.cot_template, + "Preference": self.preference_template + } + + self.repair_templates = { + "QA": Template("""<|im_start|>system +你是JSON修复器。请把给定文本修复为合法JSON对象,且仅包含字段 question/answer。 +要求: +1) 只输出一个 JSON 对象; +2) 不要输出 、解释、markdown; +3) answer 控制在80字内。 +<|im_end|> +<|im_start|>user +【原始输入】:{{ source_text }} +【候选输出】:{{ raw_output }} +请修复为目标JSON。 +<|im_end|> +<|im_start|>assistant +"""), + "CoT": Template("""<|im_start|>system +你是JSON修复器。请把给定文本修复为合法JSON对象,且仅包含字段 question/rationale/final_answer。 +要求: +1) 只输出一个 JSON 对象; +2) rationale 使用步骤化表达(建议6步); +3) 不要输出 、解释、markdown。 +<|im_end|> +<|im_start|>user +【原始输入】:{{ source_text }} +【候选输出】:{{ raw_output }} +请修复为目标JSON。 +<|im_end|> +<|im_start|>assistant +"""), + "Preference": Template("""<|im_start|>system +你是JSON修复器。请把给定文本修复为合法JSON对象,且仅包含字段 question/chosen/rejected/preference_reason。 +要求: +1) 只输出一个 JSON 对象; +2) chosen 为更优回答,rejected 为较差回答,preference_reason 必须具体; +3) 不要输出 、解释、markdown。 +<|im_end|> +<|im_start|>user +【原始输入】:{{ source_text }} +【候选输出】:{{ raw_output }} +请修复为目标JSON。 +<|im_end|> +<|im_start|>assistant +"""), + } + + def _distill_text(self, text: str) -> str: + """轻量数据蒸馏:保留核心症状/检查信息,删除冗余语气词。""" + distilled = re.sub(r"(请问|可能|大概|有点|非常|真的)", "", text) + distilled = re.sub(r"\s+", "", distilled) + return f"[蒸馏]{distilled}" + + def _augment_text(self, text: str) -> List[str]: + """轻量数据增强:结构改写 + 关键信息重排。""" + variants = [ + f"患者信息:{text}", + f"病例摘要:{text}", + f"请根据以下临床片段生成训练数据:{text}", + f"【主诉与检查】{text}", + f"医学文本(需结构化):{text}" + ] + + # 若文本包含句号,尝试做结构重排增强 + parts = [p for p in re.split(r"[。;;]", text) if p.strip()] + if len(parts) >= 2: + reordered = ";".join(parts[1:] + parts[:1]) + "。" + variants.append(f"重排病历:{reordered}") + return variants + + def build_training_corpus( + self, + raw_inputs: List[str], + target_size: int, + source_ratio: Optional[Dict[str, float]] = None, + seed: int = 42 + ) -> List[Dict[str, str]]: + """ + 构建训练语料池,支持原始/增强/蒸馏数据配比。 + 返回格式: [{"source": "original|augmented|distilled", "text": "..."}, ...] + """ + if not raw_inputs: + return [] + + if source_ratio is None: + source_ratio = {"original": 0.4, "augmented": 0.4, "distilled": 0.2} + + ratio_sum = sum(source_ratio.values()) + if ratio_sum <= 0: + raise ValueError("source_ratio 总和必须 > 0") + + normalized_ratio = {k: v / ratio_sum for k, v in source_ratio.items()} + + random.seed(seed) + original_pool = list(raw_inputs) + augmented_pool = [aug for text in raw_inputs for aug in self._augment_text(text)] + distilled_pool = [self._distill_text(text) for text in raw_inputs] + + source_pools = { + "original": original_pool, + "augmented": augmented_pool, + "distilled": distilled_pool + } + + allocated = { + k: int(target_size * normalized_ratio.get(k, 0.0)) + for k in ["original", "augmented", "distilled"] + } + + remain = target_size - sum(allocated.values()) + for key in ["original", "augmented", "distilled"]: + if remain <= 0: + break + allocated[key] += 1 + remain -= 1 + + mixed = [] + for source_name, cnt in allocated.items(): + pool = source_pools[source_name] + if not pool: + continue + for i in range(cnt): + mixed.append({"source": source_name, "text": pool[i % len(pool)]}) + + random.shuffle(mixed) + return mixed + + def _clean_json_string(self, text: str) -> str: + text = text.strip() + + # 移除 Qwen 系列常见的思考段,避免污染 JSON + text = re.sub(r"[\s\S]*?", "", text, flags=re.IGNORECASE) + # 兼容未闭合 think 标签 + text = re.sub(r"[\s\S]*$", "", text, flags=re.IGNORECASE) + text = re.sub(r"<\|im_start\|>think[\s\S]*?<\|im_end\|>", "", text, flags=re.IGNORECASE) + + # 移除 Markdown 标记 + text = re.sub(r"^```json", "", text, flags=re.MULTILINE) + text = re.sub(r"^```", "", text, flags=re.MULTILINE) + text = text.strip() + + # 🟢 增强:处理模型输出真实换行符的情况 + # 将 JSON 值里的真实换行符替换为空格,防止 json.loads 失败 + # (这是一个简单的 trick,防止 "rationale": "第一行\n第二行" 报错) + # text = text.replace('\n', ' ') + # 上面这行太暴力,可能会破坏 JSON 结构,改用 strict=False 并在失败时尝试修复 + + extracted = self._extract_first_json_object(text) + return extracted if extracted else text + + def _repair_json_syntax_only(self, text: str) -> str: + """Only fix common JSON syntax issues; never invent missing content.""" + repaired = text.strip() + repaired = re.sub(r",(\s*[}\]])", r"\1", repaired) + repaired = repaired.replace(",}", "}").replace(",]", "]") + repaired = repaired.replace("“", '"').replace("”", '"') + return repaired + + def _extract_first_json_object(self, text: str) -> Optional[str]: + start = text.find("{") + if start == -1: + return None + + in_str = False + escaped = False + depth = 0 + for i in range(start, len(text)): + ch = text[i] + if in_str: + if escaped: + escaped = False + elif ch == "\\": + escaped = True + elif ch == '"': + in_str = False + continue + + if ch == '"': + in_str = True + elif ch == "{": + depth += 1 + elif ch == "}": + depth -= 1 + if depth == 0: + return text[start:i + 1] + + # 兜底:首个 { 到最后一个 } + last = text.rfind("}") + if last > start: + return text[start:last + 1] + return None + + def _strip_reasoning_text(self, text: str) -> str: + t = text.strip() + t = re.sub(r"[\s\S]*?", "", t, flags=re.IGNORECASE) + t = re.sub(r"[\s\S]*$", "", t, flags=re.IGNORECASE) + t = re.sub(r"<\|im_start\|>think[\s\S]*?<\|im_end\|>", "", t, flags=re.IGNORECASE) + t = re.sub(r"^```json", "", t, flags=re.MULTILINE) + t = re.sub(r"^```", "", t, flags=re.MULTILINE) + t = re.sub(r"\s+", " ", t).strip() + return t + + def _looks_like_meta_or_thought(self, text: str) -> bool: + if not text: + return True + lower = text.lower().strip() + for p in self.meta_phrases: + if p.lower() in lower: + return True + if lower.startswith("嗯") or lower.startswith("好的") or lower.startswith("首先"): + return True + return False + + def _check_length_limit(self, task_type: str, data: Dict[str, Any]) -> bool: + limits = self.length_limits.get(task_type, {}) + for k, max_len in limits.items(): + v = data.get(k) + if isinstance(v, str) and len(v.strip()) > max_len: + return False + return True + + def _passes_task_quality( + self, + task_type: str, + data: Dict[str, Any], + source_text: Optional[str] = None, + ) -> bool: + if not self._check_length_limit(task_type, data): + return False + + if source_text and self._has_obvious_source_contradiction(source_text, data): + return False + + if task_type == "QA": + q = str(data.get("question", "")).strip() + a = str(data.get("answer", "")).strip() + if self._looks_like_meta_or_thought(q) or self._looks_like_meta_or_thought(a): + return False + if len(a) < 8: + return False + return True + + if task_type == "CoT": + q = str(data.get("question", "")).strip() + r = str(data.get("rationale", "")).strip() + f = str(data.get("final_answer", "")).strip() + if ( + self._looks_like_meta_or_thought(q) + or self._looks_like_model_monologue(q) + or self._looks_like_meta_or_thought(r) + or self._looks_like_meta_or_thought(f) + ): + return False + # 简单步骤判定,避免输出成口语段落 + step_hits = len(re.findall(r"(\d+[\.、]|步骤\d+|->)", r)) + if step_hits < 3: + return False + return True + + if task_type == "Preference": + c = str(data.get("chosen", "")).strip() + rj = str(data.get("rejected", "")).strip() + pr = str(data.get("preference_reason", "")).strip() + if any(self._looks_like_meta_or_thought(x) or self._looks_like_model_monologue(x) for x in [c, rj, pr]): + return False + if c == rj: + return False + if pr in self.weak_preference_reasons: + return False + return True + + return True + + def _looks_like_model_monologue(self, text: str) -> bool: + value = (text or "").strip() + if not value: + return False + monologue_patterns = [ + r"我需要", + r"我会", + r"我首先", + r"让我", + r"这让我", + r"我认为", + r"我推测", + r"需要综合这些信息", + ] + return any(re.search(pattern, value) for pattern in monologue_patterns) + + def _contains_positive_recommendation(self, text: str, terms: List[str]) -> bool: + value = text or "" + for term in terms: + for match in re.finditer(re.escape(term), value): + prefix = value[max(0, match.start() - 12):match.start()] + if any(marker in prefix for marker in ["不", "无", "无需", "不需", "忽视", "拒绝", "暂不", "不能", "避免", "慎用", "除非", "仅在"]): + continue + return True + return False + + def _is_dka_source(self, source: str) -> bool: + return ( + ("血糖" in source) + and ("尿酮" in source or "酮体" in source) + and ("pH" in source or "HCO3" in source or "酸中毒" in source) + ) + + def _is_acute_stroke_source(self, source: str) -> bool: + return ( + ("突发" in source) + and ("肢体无力" in source or "言语不清" in source or "NIHSS" in source) + and ("CT未见出血" in source or ("CT" in source and "未见出血" in source)) + ) + + def _is_bacterial_pneumonia_source(self, source: str) -> bool: + return ( + ("发热" in source and ("咳嗽" in source or "气促" in source)) + and ("白细胞" in source or "中性粒细胞" in source or "CRP" in source) + and ("片状浸润" in source or "湿啰音" in source or "肺炎" in source) + ) + + def _has_unapproved_english_tokens(self, source_text: str, generated: str) -> bool: + if not generated: + return False + + if not re.search(r"[\u4e00-\u9fff]", source_text or ""): + return False + + forbidden = { + "insulin", "volume", + } + for token in re.findall(r"[A-Za-z][A-Za-z0-9+\-]*", generated): + normalized = token.lower().strip("+-") + if normalized in forbidden: + return True + return False + + def _has_obvious_source_contradiction(self, source_text: str, data: Dict[str, Any]) -> bool: + source = source_text or "" + generated = " ".join( + str(v) + for v in data.values() + if isinstance(v, (str, int, float)) + ) + if self._has_unapproved_english_tokens(source, generated): + return True + + def has_forbidden_without_negation(term: str) -> bool: + for m in re.finditer(re.escape(term), generated): + window = generated[max(0, m.start() - 48): m.end() + 40] + if any(marker in window for marker in ["排除", "不考虑", "不符合", "不适当", "不恰当", "无关", "否定", "不是", "不应", "不得", "禁止", "无需", "不需", "不常规", "非首选", "不作为", "避免", "慎用", "除非", "仅在", "不推荐"]): + continue + return True + return False + + if any(term in generated for term in ["preference 中", "Preference 中", "chosen 应", "rejected 应", "作为 chosen", "字段固定为", "既往规则", "根据规则", "prompt", "原始的诊断建议"]): + return True + if any(term in generated for term in ["曓", "�"]): + return True + if re.search(r"依据\d{2,}", generated): + return True + if re.search(r"\binsulin\b", generated, flags=re.IGNORECASE): + return True + + contradiction_pairs = [ + ("男", ["女性", "妇科", "卵巢", "黄体破裂", "子宫", "妊娠"]), + ("女", ["男性", "睾丸", "前列腺"]), + ] + for source_marker, forbidden_terms in contradiction_pairs: + if source_marker in source and any(has_forbidden_without_negation(term) for term in forbidden_terms): + return True + + if "腹股沟" in source and "阶梯状液气平" in source: + unrelated = ["睾丸扭转", "黄体破裂", "卵巢囊肿", "盆腔炎"] + final_answer = str(data.get("final_answer", "")) + chosen = str(data.get("chosen", "")) + if data.keys() >= {"chosen", "rejected", "preference_reason"}: + rejected = str(data.get("rejected", "")) + if any(term in rejected for term in unrelated): + return True + if any(term in chosen for term in unrelated): + return True + if not ("腹股沟疝" in chosen and "肠梗阻" in chosen): + return True + if any(has_forbidden_without_negation(term) for term in unrelated): + return True + if any(term in generated for term in ["穿孔", "引流", "推挤", "减压"]): + return True + if final_answer: + unsafe_delay = r"(延迟|延误|推迟|暂缓|暂不|不急).{0,12}(外科|手术|评估|处理)|观察并.{0,8}(延迟|延误|推迟|暂缓)" + for match in re.finditer(unsafe_delay, final_answer): + prefix = final_answer[max(0, match.start() - 6):match.start()] + if any(marker in prefix for marker in ["避免", "防止", "以免", "减少"]): + continue + return True + if "观察" in final_answer and not any(term in final_answer for term in ["外科评估", "急诊", "手术", "尽快", "及时"]): + return True + + if "食管裂孔疝" in source: + chosen = str(data.get("chosen", "")) + rejected = str(data.get("rejected", "")) + if ( + self._contains_positive_recommendation(rejected, ["手术治疗", "手术评估", "外科评估"]) + and not any(term in chosen for term in ["食管裂孔疝", "裂孔疝", "手术", "外科评估"]) + ): + return True + + if all(term in source for term in ["II", "III", "aVF", "ST段抬高"]): + if any(term in generated for term in ["左心上室", "前壁心肌梗死", "高侧壁心肌梗死", "冠状动脉栓塞", "心尖端", "非心尖"]): + return True + if any(term in generated for term in ["心脏起搏器检查", "心包反射", "心包疾病"]): + return True + if re.search(r"排除.{0,10}心肌梗死|心肌梗死.{0,10}排除", generated): + return True + + if self._is_dka_source(source): + chosen = str(data.get("chosen", "")) + rejected = str(data.get("rejected", "")) + final_answer = str(data.get("final_answer", "")) + if re.search(r"HCO3-?.{0,8}(增高|升高|增加|偏高)", generated, flags=re.IGNORECASE): + return True + if any(term in generated for term in ["抗激素", "神经系统受损原因", "神经系统损伤", "神经系统受损"]): + return True + if "高血压" not in source and any(term in generated for term in ["原发性高血压", "高血压病"]): + return True + if not any(term in generated for term in ["糖尿病酮症酸中毒", "酮症酸中毒", "DKA"]): + return True + if has_forbidden_without_negation("碳酸氢钠") and "pH 6.9" not in source and "pH<6.9" not in source: + return True + if data.keys() >= {"chosen", "rejected", "preference_reason"}: + if not any(term in chosen for term in ["胰岛素", "补液", "液体复苏"]): + return True + if ( + self._contains_positive_recommendation(chosen, ["碳酸氢钠", "抗生素"]) + and self._contains_positive_recommendation(rejected, ["胰岛素", "补液", "液体复苏"]) + ): + return True + if final_answer and not any(term in final_answer for term in ["胰岛素", "补液", "液体复苏"]): + return True + + if self._is_acute_stroke_source(source): + if "缺抗性卒中" in generated: + return True + if any(term in generated for term in ["脑干梗死", "血管痉挛", "阿瑟曼征", "侧枝循环障碍"]): + return True + if has_forbidden_without_negation("SPECT"): + return True + if data.keys() >= {"chosen", "rejected", "preference_reason"}: + rejected = str(data.get("rejected", "")) + if self._contains_positive_recommendation(rejected, ["机械取栓", "取栓", "再灌注"]): + return True + if re.search(r"(先行|优先|先做|先完善).{0,12}(MRI|磁共振).{0,18}(再|后).{0,8}(溶栓|取栓|再灌注)", generated): + return True + if re.search(r"(延后|延迟|暂缓|推迟).{0,10}(溶栓|取栓|再灌注)", generated): + return True + if "CT未见出血" in source and "溶栓" in generated and re.search(r"(不应|不能|无需|不推荐).{0,8}溶栓", generated): + return True + + if self._is_bacterial_pneumonia_source(source): + chosen = str(data.get("chosen", "")) + rejected = str(data.get("rejected", "")) + if any(term in generated for term in ["腹股沟疝", "肠梗阻", "腹股沟包块"]): + return True + if "CRP升高" in source and any(term in generated for term in ["正常CRP", "CRP正常", "CRP不高", "CRP未升高"]): + return True + if any(term in generated for term in ["无呼吸道症状", "无细菌证据", "没有细菌感染证据", "缺乏细菌感染证据"]): + return True + if has_forbidden_without_negation("病毒感染"): + return True + if data.keys() >= {"chosen", "rejected", "preference_reason"}: + chosen_antiviral = self._contains_positive_recommendation(chosen, ["抗病毒"]) + rejected_antibiotic = self._contains_positive_recommendation(rejected, ["抗生素", "抗感染"]) + if chosen_antiviral and rejected_antibiotic: + return True + if not any(term in chosen for term in ["抗生素", "抗感染", "细菌性肺炎"]): + return True + + return False + + def _build_source_guardrail(self, source_text: str, task_type: Optional[str] = None) -> str: + source = source_text or "" + rules: List[str] = [] + if "男" in source: + rules.append("病例为男性。") + if "女" in source: + rules.append("病例为女性。") + if "腹股沟" in source and "包块" in source: + rules.append("腹股沟包块合并阶梯状液气平时,应围绕嵌顿性腹股沟疝合并肠梗阻分析。") + rules.append("所有字段禁止出现穿孔、引流、推挤、减压等原文未给出的并发症或处置。") + rules.append("CoT 任务中,final_answer 必须建议尽快外科或急诊外科评估,不得建议观察、延迟外科评估或延迟手术。") + rules.append("Preference 任务中,chosen 必须字面包含:嵌顿性腹股沟疝合并肠梗阻,并建议尽快外科评估;不得把卵巢囊肿、盆腔炎、睾丸扭转、阑尾肿瘤等作为 chosen。") + rules.append("Preference 任务中,rejected 不得是疾病名,严禁输出卵巢囊肿、盆腔炎、睾丸扭转等其他诊断名称;必须用同一病例的低质量处理建议作为 rejected,例如仅建议观察、延误外科评估、忽视肠梗阻证据或未及时处理嵌顿疝。") + if "食管裂孔疝" in source: + rules.append("食管裂孔疝病例应同时覆盖反流性食管炎、食管裂孔疝和反流相关咳喘。") + rules.append("Preference 任务中,chosen 应是更完整答案;不得把手术治疗、手术评估或外科评估作为 rejected 的优点。") + if all(term in source for term in ["II", "III", "aVF", "ST段抬高"]): + rules.append("II、III、aVF导联ST段抬高合并肌钙蛋白升高时,应明确为急性下壁STEMI或下壁心肌梗死。") + rules.append("处理建议应聚焦急诊心内科评估、抗栓治疗、冠脉造影评估和再灌注策略。") + if self._is_dka_source(source): + rules.append("血糖显著升高、尿酮体阳性、pH/HCO3-提示酸中毒时,应围绕糖尿病酮症酸中毒分析。") + rules.append("处理原则必须包括补液或液体复苏、静脉胰岛素、钾/电解质监测与纠正,并寻找诱因。") + if task_type == "Preference": + rules.append("Preference 的 chosen 必须同时包含诊断和处理:糖尿病酮症酸中毒、补液、静脉胰岛素、电解质监测纠正;rejected 应写同病例低质量处置,例如仅观察或只控制血糖而遗漏补液和电解质管理。") + rules.append("治疗表述只使用中文胰岛素,不使用英文 insulin;不要输出编号残片。") + rules.append("只输出上述诊断依据和处理原则,不扩展原文未提供的其他系统病因或常规外治疗。") + if self._is_acute_stroke_source(source): + rules.append("突发偏瘫/言语不清且头颅CT未见出血时,应按急性缺血性卒中路径分析。") + rules.append("处置应包括卒中中心评估、静脉溶栓时间窗/禁忌评估、必要时机械取栓评估、血压和血糖管理。") + rules.append("不得无依据写脑干梗死、血管痉挛或SPECT;不得要求先做MRI/SPECT而延误溶栓或再灌注评估。") + if task_type == "Preference": + rules.append("Preference 中 chosen 不得写既往规则、根据规则或 prompt 话术;rejected 不得否定机械取栓或再灌注评估,应写同病例低质量回答,例如仅观察、延误溶栓、忽视CT未见出血或忽视时间窗。") + if self._is_bacterial_pneumonia_source(source): + rules.append("儿童发热咳嗽、湿啰音、白细胞/中性粒细胞/CRP升高和片状浸润影时,应优先围绕细菌性肺炎分析。") + if task_type == "Preference": + rules.append("Preference 中 chosen 应支持经验性抗生素或抗感染治疗及支持治疗;不得把抗病毒优先方案作为 chosen。") + rules.append("Preference 中 rejected 必须是同病例低质量回答,例如仅抗病毒、仅观察、延误抗生素或忽视细菌感染证据;不得写不适用、信息不足、妇科疾病或其他无关内容。") + rules.append("Preference 的 rejected 不得写无呼吸道症状,不得写无细菌证据,不得写缺乏细菌感染证据;因为原始病例已经有发热咳嗽、白细胞/CRP升高和片状浸润影。") + if rules: + rules.append("以上规则只用于约束生成,禁止把规则原句、字段名或 prompt 要求写入输出内容。") + return " ".join(rules) + + def _render_prompt(self, task_type: str, text: str) -> str: + if task_type not in self.task_templates: + raise ValueError(f"不支持的 task_type: {task_type}") + + if task_type == "QA": + return self._render_qa_fast_prompt(text) + if task_type == "CoT": + return self._render_cot_native_prompt(text) + if task_type == "Preference": + return self._render_preference_native_prompt(text) + raise ValueError(f"不支持的 task_type: {task_type}") + + def _render_qa_fast_prompt(self, text: str) -> str: + compact = text.strip() + guardrail = self._build_source_guardrail(compact, "QA") + if self._qa_uses_native_template: + messages = [ + { + "role": "system", + "content": ( + "Generate one medical QA JSON object from the source text. " + "Output JSON only. Do not output explanations or . " + "Use exactly two fields: question and answer. " + "Keep answer concise and grounded in the source text. " + f"{guardrail}" + ), + }, + { + "role": "user", + "content": compact, + }, + ] + return self._render_native_chat_template(messages, enable_thinking=False) + + return ( + "<|im_start|>system\n" + "Generate one medical QA JSON object from the source text. " + "Output JSON only. Do not output explanations or . " + "Use exactly two fields: question and answer. " + "Keep answer concise and grounded in the source text. " + f"{guardrail}\n" + "<|im_end|>\n" + "<|im_start|>user\n" + f"{compact}\n" + "<|im_end|>\n" + "<|im_start|>assistant\n" + "\n\n\n\n" + ) + + def _render_cot_native_prompt(self, text: str) -> str: + compact = text.strip() + guardrail = self._build_source_guardrail(compact, "CoT") + if self._qa_uses_native_template: + messages = [ + { + "role": "system", + "content": ( + "你是资深临床医生。请基于用户给出的中文病例生成一个 CoT JSON 对象。" + "只能输出 JSON,不要输出解释或 。" + "字段固定为 question、rationale、final_answer。" + "question 必须是一个简短的临床问题,不得写模型自述、推理过程、'我需要'或'这让我'。" + "rationale 必须是一个中文字符串,不要使用数组;必须包含六个编号:1. 2. 3. 4. 5. 6.。" + "每个编号步骤必须引用输入病例中的症状、检查或处置依据,每步尽量不超过35字。" + "final_answer 必须与病例一致,不得引入输入中不存在的症状或检查。" + f"{guardrail}" + ), + }, + {"role": "user", "content": compact}, + ] + return self._render_native_chat_template(messages, enable_thinking=False) + return self.cot_template.render(question=text) + + def _render_preference_native_prompt(self, text: str) -> str: + compact = text.strip() + guardrail = self._build_source_guardrail(compact, "Preference") + if self._qa_uses_native_template: + messages = [ + { + "role": "system", + "content": ( + "你是医疗数据工程师。请基于用户给出的中文病例生成一个偏好学习 JSON 对象。" + "只能输出 JSON,不要输出解释或 。" + "字段固定为 question、chosen、rejected、preference_reason。" + "chosen 必须是准确、安全、完整的医学回答。" + "rejected 必须是明显较差但与同一病例相关的回答,不得写成无关疾病。" + "rejected 应写成同一病例下的错误处置、遗漏关键证据或不安全建议,不要列举与病例性别/部位冲突的其他疾病。" + "每个字段保持简短,避免长篇背景解释。" + "如果病例为男性,禁止输出妇科疾病;如果病例为女性,禁止输出男性生殖系统疾病。" + f"{guardrail}" + "preference_reason 必须具体比较 chosen 为什么更好。" + ), + }, + {"role": "user", "content": compact}, + ] + return self._render_native_chat_template(messages, enable_thinking=False) + return self.preference_template.render(question=text) + + def _render_repair_prompt( + self, + task_type: str, + source_text: str, + raw_output: str, + repair_note: Optional[str] = None, + ) -> str: + if task_type not in self.repair_templates: + raise ValueError(f"不支持的 task_type: {task_type}") + # 限制候选输出长度,避免修复阶段 prompt 过长 + clipped = (raw_output or "")[:2400] + note = f"\n质量校验失败原因:{repair_note}" if repair_note else "" + if self._qa_uses_native_template: + fields = "/".join(self.required_fields.get(task_type, [])) + guardrail = self._build_source_guardrail(source_text, task_type) + groin_repair_rules = "" + if "腹股沟" in (source_text or "") and "阶梯状液气平" in (source_text or ""): + groin_repair_rules = ( + "腹股沟包块合并阶梯状液气平时,chosen 必须写嵌顿性腹股沟疝合并肠梗阻并建议尽快外科评估。" + "腹股沟包块合并阶梯状液气平的 Preference 修复中,chosen 必须字面包含:嵌顿性腹股沟疝合并肠梗阻;rejected 不得是疾病名,只能写同一病例下的低质量处置。" + "腹股沟包块合并阶梯状液气平时,所有字段禁止出现穿孔、引流、推挤、减压等原文未给出的并发症或处置。" + "腹股沟包块合并肠梗阻风险时,CoT 的 final_answer 不得建议观察、延迟外科评估或延迟手术。" + ) + messages = [ + { + "role": "system", + "content": ( + f"你是严格的 JSON 修复器。只输出一个合法 JSON 对象,字段固定为 {fields}。" + "不要输出解释、markdown 或 。" + "只能基于原始输入和候选输出修复结构,不得编造原文不存在的诊断、症状或检查。" + "CoT 的 rationale 必须写成单个编号字符串,不得使用数组;必须包含六个编号:1. 2. 3. 4. 5. 6.;final_answer 必须存在且简短。" + "Preference 的 rejected 必须是同一病例下的低质量回答,不得用与病例性别或部位冲突的其他疾病凑数。" + "如果 Preference 候选 rejected 是离题疾病或其他诊断名称,必须改写为同病例低质量处置建议,例如仅建议观察、延误外科评估、忽视关键检查或遗漏高危证据。" + "如果 Preference 候选 chosen 是离题疾病或其他错误诊断,必须改写为原始输入支持的正确答案。" + f"{groin_repair_rules}" + "CoT 的 final_answer 必须是安全处置建议,不得输出明显错误的首要处理。" + f"{guardrail}" + ), + }, + { + "role": "user", + "content": ( + f"原始输入:{source_text}\n" + f"候选输出:{clipped}\n" + f"{note}\n" + "请修复为目标 JSON。" + ), + }, + ] + return self._render_native_chat_template(messages, enable_thinking=False) + return self.repair_templates[task_type].render(source_text=source_text, raw_output=clipped) + + def _build_repair_retry_note(self, task_type: str, source_text: str, raw_output: str) -> str: + source = source_text or "" + notes: List[str] = ["上一轮输出仍未通过质量校验,必须重写为合格 JSON。"] + if "腹股沟" in source and "阶梯状液气平" in source: + notes.append("删除所有字段中的禁用并发症或处置词,不要复述上一轮中的禁用表述。") + notes.append("CoT final_answer 只保留嵌顿性腹股沟疝合并肠梗阻和尽快外科评估。") + notes.append("Preference chosen 必须包含嵌顿性腹股沟疝合并肠梗阻,rejected 只能是同病例低质量处置。") + if raw_output: + notes.append("不要保留候选输出中触发上述问题的表达。") + return " ".join(notes) + + def _sanitize_failed_repair_output(self, source_text: str, raw_output: str) -> str: + sanitized = raw_output or "" + if "腹股沟" in (source_text or "") and "阶梯状液气平" in (source_text or ""): + sanitized = re.sub(r"避免延误导致[^。;;,,\"]+", "避免延误处理", sanitized) + sanitized = re.sub(r"防止[^。;;,,\"]+", "避免延误处理", sanitized) + sanitized = re.sub(r"(穿孔|肠穿孔|引流|推挤|减压)", "", sanitized) + if self._is_dka_source(source_text or ""): + sanitized = re.sub(r"(抗激素|神经系统受损原因|神经系统损伤|神经系统受损|碳酸氢钠|抗生素)", "", sanitized) + sanitized = re.sub(r"\binsulin\b", "", sanitized, flags=re.IGNORECASE) + sanitized = re.sub(r"依据\d+", "", sanitized) + if self._is_bacterial_pneumonia_source(source_text or ""): + sanitized = sanitized.replace("无呼吸道症状或无细菌证据", "忽视已有细菌感染证据") + sanitized = sanitized.replace("无呼吸道症状", "有呼吸道症状") + sanitized = sanitized.replace("无细菌证据", "忽视已有细菌感染证据") + sanitized = sanitized.replace("缺乏细菌感染证据", "忽视已有细菌感染证据") + return sanitized[:1800] + + def _render_second_repair_prompt(self, task_type: str, source_text: str, raw_output: str) -> str: + sanitized = self._sanitize_failed_repair_output(source_text, raw_output) + if self._qa_uses_native_template: + fields = "/".join(self.required_fields.get(task_type, [])) + guardrail = self._build_source_guardrail(source_text, task_type) + source = source_text or "" + groin_instruction = "" + if "腹股沟" in source and "阶梯状液气平" in source: + groin_instruction = "腹股沟包块合并阶梯状液气平时,诊断和处置只写:嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。" + content = ( + f"你是严格的 JSON 二次修复器。只输出一个合法 JSON 对象,字段固定为 {fields}。" + "请完全重写,不要沿用上一轮原句,不要输出解释、markdown 或 。" + "必须只根据原始输入和允许的医学结论生成,不能扩展原文未给出的并发症或处置。" + "CoT 的 rationale 必须写成单个编号字符串,不得使用数组;必须包含六个编号:1. 2. 3. 4. 5. 6.;final_answer 必须存在。" + f"{groin_instruction}" + f"{guardrail}" + ) + if task_type == "CoT": + user_content = ( + f"原始输入:{source_text}\n" + "上一轮候选输出结构不合格,已丢弃。请只基于原始输入重新生成目标 JSON。" + ) + else: + user_content = ( + f"原始输入:{source_text}\n" + f"上一轮失败输出(已清理禁用词):{sanitized}\n" + "请重新生成目标 JSON。" + ) + messages = [ + {"role": "system", "content": content}, + {"role": "user", "content": user_content}, + ] + return self._render_native_chat_template(messages, enable_thinking=False) + return self._render_repair_prompt(task_type, source_text, sanitized, self._build_repair_retry_note(task_type, source_text, sanitized)) + + def _normalize_parsed_data(self, task_type: str, data: Any) -> Optional[Dict[str, Any]]: + if not isinstance(data, dict): + return None + + allowed = self.required_fields.get(task_type, []) + if task_type == "QA" and "answer" not in data: + for alias in ["处理原则", "诊断", "结论", "回答", "answer_text"]: + if alias in data: + data = dict(data) + data["answer"] = data.get(alias) + break + normalized = {key: data.get(key) for key in allowed} + + if task_type == "CoT" and isinstance(normalized.get("rationale"), list): + normalized["rationale"] = "".join( + f"{i + 1}. {str(step).strip()}" + for i, step in enumerate(normalized["rationale"]) + if str(step).strip() + ) + elif task_type == "CoT" and isinstance(normalized.get("rationale"), str): + normalized["rationale"] = self._normalize_cot_rationale_text(normalized["rationale"]) + + return normalized + + def _normalize_cot_rationale_text(self, rationale: str) -> str: + text = re.sub(r"\s+", " ", rationale or "").strip() + if not text: + return text + if len(re.findall(r"(\d+[\.、]|步骤\d+|->)", text)) >= 3: + return text + + parts = [p.strip(" ;;。") for p in re.split(r"[。;;]", text) if p.strip(" ;;。")] + if len(parts) < 3: + comma_parts = [p.strip(" ,,") for p in re.split(r"[,,]", text) if p.strip(" ,,")] + if len(comma_parts) >= 4: + parts = comma_parts + + if len(parts) < 3: + return text + + steps = parts[:6] + return "".join(f"{i + 1}. {step}。" for i, step in enumerate(steps)) + + def _validate_generated_data( + self, + task_type: str, + data: Dict[str, Any], + source_text: Optional[str] = None, + ) -> bool: + required = self.required_fields.get(task_type, []) + if not required: + return False + if set(data.keys()) != set(required): + return False + for key in required: + value = data.get(key) + if value is None: + return False + if isinstance(value, str) and not value.strip(): + return False + return self._passes_task_quality(task_type, data, source_text) + + def _build_sampling_params(self, task_type: str) -> SamplingParams: + # 延迟优化策略:QA/Preference 限长提速;CoT 放宽长度获取更详细推理 + if task_type == "QA": + return SamplingParams( + temperature=0.0, + top_p=0.8, + max_tokens=220, + stop=["<|im_end|>"], + repetition_penalty=1.0, + ) + + if task_type == "Preference": + return SamplingParams( + temperature=0.0, + top_p=1.0, + max_tokens=320, + stop=["<|im_end|>"], + repetition_penalty=1.03, + structured_outputs=self._structured_json_params("Preference"), + ) + + # CoT:不刻意限短,保留较大 token 预算生成更长推理 + return SamplingParams( + temperature=0.0, + top_p=1.0, + max_tokens=900, + stop=["<|im_end|>"], + repetition_penalty=1.05, + structured_outputs=self._structured_json_params("CoT"), + ) + + def _build_repair_sampling_params(self, task_type: str) -> SamplingParams: + # 修复阶段使用更低随机性,优先稳定产出结构化 JSON + if task_type == "QA": + max_tokens = 220 + elif task_type == "CoT": + max_tokens = 1400 + else: + max_tokens = 360 + + return SamplingParams( + temperature=0.0, + top_p=0.9, + max_tokens=max_tokens, + stop=["<|im_end|>"], + repetition_penalty=1.0, + structured_outputs=self._structured_json_params(task_type) if task_type in ["CoT", "Preference"] else None, + ) + + def _structured_json_params(self, task_type: str) -> Any: + schema = self._json_schema_for_task(task_type) + if StructuredOutputsParams is not None: + return StructuredOutputsParams(json=schema, disable_any_whitespace=True) + return {"json": schema, "disable_any_whitespace": True} + + def _json_schema_for_task(self, task_type: str) -> Dict[str, Any]: + if task_type == "CoT": + return { + "type": "object", + "additionalProperties": False, + "required": ["question", "rationale", "final_answer"], + "properties": { + "question": {"type": "string", "minLength": 4, "maxLength": 220}, + "rationale": { + "type": "string", + "minLength": 40, + "maxLength": 900, + }, + "final_answer": {"type": "string", "minLength": 8, "maxLength": 220}, + }, + } + if task_type == "Preference": + return { + "type": "object", + "additionalProperties": False, + "required": ["question", "chosen", "rejected", "preference_reason"], + "properties": { + "question": {"type": "string", "minLength": 4, "maxLength": 220}, + "chosen": {"type": "string", "minLength": 8, "maxLength": 180}, + "rejected": {"type": "string", "minLength": 8, "maxLength": 180}, + "preference_reason": {"type": "string", "minLength": 12, "maxLength": 220}, + }, + } + raise ValueError(f"不支持的 task_type: {task_type}") + + def _truncate_text_at_boundary(self, text: str, limit: int) -> str: + value = text.strip() + if len(value) <= limit: + return value + + cut = value[:limit].rstrip() + + sentence_marks = "。!?.!?" + last_sentence = max(cut.rfind(mark) for mark in sentence_marks) + if last_sentence >= 20: + return cut[:last_sentence + 1].rstrip() + + phrase_marks = ";;,,、::" + last_phrase = max(cut.rfind(mark) for mark in phrase_marks) + if last_phrase >= 20: + return cut[:last_phrase].rstrip() + + last_space = cut.rfind(" ") + if last_space >= 20: + return cut[:last_space].rstrip(" ,;:") + + return cut.rstrip() + + def _truncate_qa_fields(self, data: Dict[str, Any]) -> Dict[str, Any]: + normalized = dict(data) + question = str(normalized.get("question", "")).strip() + answer = str(normalized.get("answer", "")).strip() + + q_limit = self.length_limits["QA"]["question"] + a_limit = self.length_limits["QA"]["answer"] + + normalized["question"] = self._truncate_text_at_boundary(question, q_limit) + normalized["answer"] = self._truncate_text_at_boundary(answer, a_limit) + + return normalized + + def _try_parse_and_validate( + self, + task_type: str, + text: str, + source_text: Optional[str] = None, + ) -> Optional[Dict[str, Any]]: + clean_text = self._clean_json_string(text) + candidates = [ + clean_text, + self._repair_json_syntax_only(clean_text), + clean_text.replace('\n', '\\n'), + self._repair_json_syntax_only(clean_text).replace('\n', '\\n'), + ] + + for candidate in candidates: + try: + data = json.loads(candidate, strict=False) + data = self._normalize_parsed_data(task_type, data) + if data is None: + continue + if task_type == "QA": + data = self._truncate_qa_fields(data) + if self._validate_generated_data(task_type, data, source_text): + return data + except Exception: + continue + return None + + def _repair_failed_batch(self, task_type: str, repair_items: List[Dict[str, Any]]) -> Dict[int, Dict[str, Any]]: + """ + 对首轮失败样本执行二阶段修复。 + repair_items: [{"idx": int, "source_text": str, "raw_output": str}, ...] + 返回: {idx: {"status": ..., "data": ...}} + """ + if not repair_items: + return {} + + prompts = [ + self._render_repair_prompt(task_type, item["source_text"], item.get("raw_output", "")) + for item in repair_items + ] + repair_outputs = self.llm.generate(prompts, self._build_repair_sampling_params(task_type)) + + repaired_result_map: Dict[int, Dict[str, Any]] = {} + retry_items: List[Dict[str, Any]] = [] + for item, output in zip(repair_items, repair_outputs): + idx = item["idx"] + repaired_text = output.outputs[0].text if output.outputs else "" + parsed = self._try_parse_and_validate(task_type, repaired_text, item["source_text"]) + if parsed is not None: + repaired_result_map[idx] = { + "status": "success", + "data": parsed, + "repaired": True, + } + continue + + retry_items.append({ + "idx": idx, + "source_text": item["source_text"], + "raw_output": item.get("raw_output", ""), + "repair_raw_output": repaired_text, + }) + + if retry_items: + retry_prompts = [ + self._render_second_repair_prompt(task_type, item["source_text"], item.get("repair_raw_output", "")) + for item in retry_items + ] + retry_outputs = self.llm.generate(retry_prompts, self._build_repair_sampling_params(task_type)) + + for item, output in zip(retry_items, retry_outputs): + idx = item["idx"] + retry_text = output.outputs[0].text if output.outputs else "" + parsed = self._try_parse_and_validate(task_type, retry_text, item["source_text"]) + if parsed is not None: + repaired_result_map[idx] = { + "status": "success", + "data": parsed, + "repaired": True, + "repair_attempts": 2, + } + continue + + repaired_result_map[idx] = { + "status": "failed", + "reason": "repair_failed", + "raw_output": item.get("raw_output", ""), + "repair_raw_output": item.get("repair_raw_output", ""), + "second_repair_raw_output": retry_text, + } + + for item in retry_items: + idx = item["idx"] + if idx in repaired_result_map: + continue + repaired_result_map[idx] = { + "status": "failed", + "reason": "repair_failed", + "raw_output": item.get("raw_output", ""), + "repair_raw_output": item.get("repair_raw_output", ""), + } + + return repaired_result_map + + def generate_data_batch(self, task_type: str, inputs: List[str]) -> List[Dict[str, Any]]: + if task_type not in self.task_templates: + raise ValueError(f"不支持的 task_type: {task_type}") + + prompts = [] + for text in inputs: + prompts.append(self._render_prompt(task_type, text)) + + sampling_params = self._build_sampling_params(task_type) + + outputs = self.llm.generate(prompts, sampling_params) + + # 先占位,首轮失败的样本进入二阶段修复 + results: List[Optional[Dict[str, Any]]] = [None] * len(outputs) + repair_items: List[Dict[str, Any]] = [] + + for i, output in enumerate(outputs): + generated_text = output.outputs[0].text if output.outputs else "" + parsed = self._try_parse_and_validate(task_type, generated_text, inputs[i]) + if parsed is not None: + results[i] = {"status": "success", "data": parsed} + continue + + # 首轮直接失败,进入修复阶段 + repair_items.append({ + "idx": i, + "source_text": inputs[i], + "raw_output": generated_text, + }) + + repaired_map = self._repair_failed_batch(task_type, repair_items) + for item in repair_items: + idx = item["idx"] + if idx in repaired_map: + results[idx] = repaired_map[idx] + else: + results[idx] = { + "status": "failed", + "reason": "repair_missing", + "raw_output": item.get("raw_output", ""), + } + + # 理论上不应存在 None,这里兜底 + for i, r in enumerate(results): + if r is None: + results[i] = { + "status": "failed", + "reason": "internal_empty_result", + "raw_output": "", + } + + + return [r for r in results if r is not None] + + def _extract_case_parts(self, source_text: str) -> Dict[str, str]: + demo = "" + symptom = "" + finding = "" + + m_demo = re.search(r"^(.*?)。主诉[::]", source_text) + if m_demo: + demo = m_demo.group(1).strip() + + m_symptom = re.search(r"主诉[::](.*?)。查体", source_text) + if m_symptom: + symptom = m_symptom.group(1).strip() + + m_finding = re.search(r"查体及辅助检查[::](.*?)(。|$)", source_text) + if m_finding: + finding = m_finding.group(1).strip() + + if not demo and not symptom and not finding: + return { + "demo": "患者", + "symptom": source_text.strip()[:60], + "finding": "检查信息待补充", + } + + return { + "demo": demo or "患者", + "symptom": symptom or "症状待补充", + "finding": finding or "检查信息待补充", + } + + def _infer_primary_assessment(self, finding: str) -> str: + f = finding or "" + if "ST段抬高" in f: + return "急性冠脉综合征风险" + if "脑梗死" in f: + return "脑梗死相关神经功能受损" + if "斑片影" in f: + return "肺部炎症性病变" + if "结石" in f: + return "结石相关器官病变" + if "尿蛋白" in f: + return "肾脏受损风险" + if "白细胞升高" in f or "CRP升高" in f: + return "感染或炎症反应" + return "临床异常需进一步评估" + +if __name__ == "__main__": + pass diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/download.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/download.py new file mode 100644 index 00000000..a0f8c276 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/download.py @@ -0,0 +1,75 @@ +import argparse +import os +from pathlib import Path + +from modelscope import snapshot_download + + +def _ensure_writable_dir(path: str) -> Path: + p = Path(path).expanduser().resolve() + p.mkdir(parents=True, exist_ok=True) + if not os.access(p, os.W_OK): + raise PermissionError(f"目录不可写: {p}") + return p + + +def main(): + parser = argparse.ArgumentParser(description="下载 ModelScope 模型") + parser.add_argument( + "--model_id", + default="testUser/Qwen3-1.7b-Medical-R1-sft", + help="ModelScope 模型 ID" + ) + parser.add_argument( + "--cache_dir", + default=os.getenv("MODELSCOPE_CACHE", "~/.cache/modelscope"), + help="模型缓存目录(必须可写)" + ) + parser.add_argument( + "--download_train_artifacts", + action="store_true", + help="是否下载训练中间文件(optimizer/rng_state/trainer_state 等)" + ) + args = parser.parse_args() + + cache_dir = _ensure_writable_dir(args.cache_dir) + print(f"📦 准备下载模型: {args.model_id}") + print(f"📂 缓存目录: {cache_dir}") + + # 默认只下推理需要的文件,避免拉取超大训练中间产物 + allow_patterns = None + ignore_patterns = None + if not args.download_train_artifacts: + allow_patterns = [ + "*.json", + "*.model", + "*.txt", + "*.safetensors", + "*.bin", + "tokenizer*", + "vocab*", + "merges*", + "configuration*", + "README*", + ] + ignore_patterns = [ + "optimizer.pt", + "rng_state.pth", + "trainer_state.json", + "scheduler.pt", + "training_args.bin", + "*.ckpt", + ] + + model_dir = snapshot_download( + args.model_id, + cache_dir=str(cache_dir), + allow_patterns=allow_patterns, + ignore_patterns=ignore_patterns, + ) + + print(f"✅ 模型已下载到: {model_dir}") + + +if __name__ == "__main__": + main() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/final_delivery_part1.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/final_delivery_part1.py new file mode 100644 index 00000000..25642fd1 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/final_delivery_part1.py @@ -0,0 +1,226 @@ +import os +import time +import json +import random +import pandas as pd +import matplotlib.pyplot as plt +from datetime import datetime +from pathlib import Path +from typing import List, Dict + +# 引入核心合成引擎 +from data_synthesizer import MedicalDataSynthesizer + +# ========================================== +# 配置区域 +# ========================================== +def resolve_model_path() -> str: + candidates = [ + os.getenv("MODEL_PATH"), + os.getenv("DATA_SYNTHESIS_MODEL_PATH"), + "/model/Qwen/Qwen3-1___7b-Medical-R1-sft", + str(Path.home() / ".cache/modelscope/testUser/Qwen3-1___7b-Medical-R1-sft"), + ] + for path in candidates: + if path and os.path.exists(path): + return path + return os.getenv("MODEL_PATH") or "/model/Qwen/Qwen3-1___7b-Medical-R1-sft" + + +MODEL_PATH = resolve_model_path() +TEST_SAMPLE_COUNT = 100 # 测试样本总数 (50 QA + 50 CoT) +OUTPUT_BASE_DIR = "outputs" +TASK_RATIO = {"QA": 0.4, "CoT": 0.4, "Preference": 0.2} +SOURCE_MIX_RATIO = {"original": 0.4, "augmented": 0.4, "distilled": 0.2} + +# ========================================== +# 工具函数 +# ========================================== +def generate_mock_inputs(num_samples=50): + """生成模拟病历输入""" + symptoms = ["持续性干咳", "右上腹剧痛", "胸闷气短", "双下肢水肿", "突发言语不清", "高热寒战", "关节红肿痛", "视力模糊"] + durations = ["3天", "2周", "5小时", "反复发作1年", "晨起加重"] + demographics = ["男性,45岁", "女性,65岁", "患儿,5岁", "老年男性,78岁", "孕妇,28岁"] + findings = ["白细胞升高", "CT示斑片影", "B超示结石", "心电图ST段抬高", "MRI示脑梗死", "尿蛋白+++"] + + return [f"{random.choice(demographics)}。主诉:{random.choice(symptoms)}{random.choice(durations)}。查体及辅助检查:{random.choice(findings)}。" for _ in range(num_samples)] + +def setup_output_dir(): + """创建带时间戳的输出目录""" + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + dir_path = os.path.join(OUTPUT_BASE_DIR, timestamp) + os.makedirs(dir_path, exist_ok=True) + print(f"📂 [System] 输出目录已创建: {dir_path}") + return dir_path + +def save_json(data: List, filepath: str): + """保存数据为 JSON 格式""" + with open(filepath, 'w', encoding='utf-8') as f: + json.dump(data, f, ensure_ascii=False, indent=2) + print(f"💾 [File] 已保存: {filepath} ({len(data)} 条)") + +def visualize_report(df: pd.DataFrame, save_path: str): + """生成专业的可视化验收报告""" + plt.switch_backend('agg') # Docker 环境必备 + + # 设置画布风格 + plt.style.use('ggplot') + fig, axs = plt.subplots(2, 2, figsize=(14, 10)) + fig.suptitle(f'Ascend 910B Data Synthesis Acceptance Report\nTotal Samples: {len(df)}', fontsize=16) + + # 1. 延迟对比图 (Bar Chart) + qa_lat = df[df['task_type']=='QA']['latency'].mean() + cot_lat = df[df['task_type']=='CoT']['latency'].mean() + + bars = axs[0, 0].bar(['QA', 'CoT'], [qa_lat, cot_lat], color=['#3498db', '#e67e22']) + axs[0, 0].axhline(y=3.0, color='red', linestyle='--', linewidth=2, label='Max Limit (3s)') + axs[0, 0].set_title('Average Latency (Batch Mode)') + axs[0, 0].set_ylabel('Seconds per Item') + axs[0, 0].legend() + # 在柱子上标数值 + for bar in bars: + height = bar.get_height() + axs[0, 0].text(bar.get_x() + bar.get_width()/2., height, + f'{height:.3f}s', ha='center', va='bottom') + + # 2. 成功率 (Pie Chart) + status_counts = df['status'].value_counts() + colors = ['#2ecc71', '#e74c3c'] if 'failed' in status_counts else ['#2ecc71'] + axs[0, 1].pie(status_counts, labels=status_counts.index, autopct='%1.1f%%', + colors=colors, startangle=90, explode=[0.1]*len(status_counts)) + axs[0, 1].set_title('Data Format Integrity') + + # 3. 延迟分布直方图 (Histogram) + axs[1, 0].hist(df['latency'], bins=20, color='#9b59b6', alpha=0.7, edgecolor='white') + axs[1, 0].set_title('Latency Distribution') + axs[1, 0].set_xlabel('Latency (s)') + axs[1, 0].set_ylabel('Count') + + # 4. 任务详情表 (Table) + cell_text = [ + ["Model", "Qwen2.5-7B-Instruct"], + ["Hardware", "Ascend 910B + 32G RAM"], + ["Inference", "vLLM (Ascend) + Batching"], + ["Total QA", len(df[df['task_type']=='QA'])], + ["Total CoT", len(df[df['task_type']=='CoT'])], + ["Pass Rate", f"{(df['status']=='success').mean()*100:.1f}%"] + ] + axs[1, 1].axis('tight') + axs[1, 1].axis('off') + table = axs[1, 1].table(cellText=cell_text, loc='center', cellLoc='left') + table.auto_set_font_size(False) + table.set_fontsize(12) + table.scale(1, 2) + axs[1, 1].set_title('Test Environment & Stats') + + plt.tight_layout() + plt.savefig(save_path, dpi=150) + print(f"📊 [Plot] 可视化报告已保存: {save_path}") + +# ========================================== +# 主逻辑 +# ========================================== +def main(): + # 1. 准备环境 + output_dir = setup_output_dir() + synthesizer = MedicalDataSynthesizer(MODEL_PATH) + + # 2. 生成模拟输入并执行“原始/增强/蒸馏”配比 + total_inputs = generate_mock_inputs(TEST_SAMPLE_COUNT) + mixed_pool = synthesizer.build_training_corpus( + raw_inputs=total_inputs, + target_size=TEST_SAMPLE_COUNT, + source_ratio=SOURCE_MIX_RATIO, + seed=42, + ) + mixed_texts = [x["text"] for x in mixed_pool] + + qa_cnt = int(TEST_SAMPLE_COUNT * TASK_RATIO["QA"]) + cot_cnt = int(TEST_SAMPLE_COUNT * TASK_RATIO["CoT"]) + pref_cnt = TEST_SAMPLE_COUNT - qa_cnt - cot_cnt + + qa_inputs = mixed_texts[:qa_cnt] + cot_inputs = mixed_texts[qa_cnt: qa_cnt + cot_cnt] + pref_inputs = mixed_texts[qa_cnt + cot_cnt: qa_cnt + cot_cnt + pref_cnt] + + metrics_data = [] # 用于记录 CSV 指标 + + print("\n" + "="*50) + print(f"🚀 开始验收测试 (Batch Mode)") + print(f"🎯 目标: 生成 {TEST_SAMPLE_COUNT} 条数据并归档 (QA/CoT/Preference)") + print("="*50) + + task_inputs = { + "QA": qa_inputs, + "CoT": cot_inputs, + "Preference": pref_inputs, + } + + task_latencies = {} + success_payload = {"QA": [], "CoT": [], "Preference": []} + + for task_type, task_items in task_inputs.items(): + print(f"Processing {len(task_items)} {task_type} items...") + t_start = time.time() + outputs = synthesizer.generate_data_batch(task_type, task_items) + t_end = time.time() + + per_item_latency = (t_end - t_start) / max(len(task_items), 1) + task_latencies[task_type] = per_item_latency + + for res in outputs: + metrics_data.append({ + "task_type": task_type, + "latency": per_item_latency, + "status": res['status'], + "raw_text_len": len(str(res.get('data', ''))), + "data": res.get("data", {}), + }) + if res['status'] == 'success': + success_payload[task_type].append(res['data']) + + # ========================================== + # 3. 保存交付件 (Artifacts) + # ========================================== + print("\n📦 [System] 正在保存交付件...") + + # 保存 1: 生成的数据文件 (JSON) + save_json(success_payload["QA"], os.path.join(output_dir, "generated_qa.json")) + save_json(success_payload["CoT"], os.path.join(output_dir, "generated_cot.json")) + save_json(success_payload["Preference"], os.path.join(output_dir, "generated_preference.json")) + + # 保存 2: 原始指标 (CSV) + df = pd.DataFrame(metrics_data) + csv_path = os.path.join(output_dir, "benchmark_metrics.csv") + df.to_csv(csv_path, index=False) + print(f"💾 [File] 指标数据已保存: {csv_path}") + + # 保存 3: 可视化报告 (PNG) + png_path = os.path.join(output_dir, "visual_report.png") + visualize_report(df, png_path) + + # 保存 4: 汇总摘要 (JSON) + summary = { + "timestamp": datetime.now().isoformat(), + "model": MODEL_PATH, + "total_samples": len(df), + "task_ratio": TASK_RATIO, + "source_mix_ratio": SOURCE_MIX_RATIO, + "success_rate": float((df['status']=='success').mean()), + "avg_latency_qa": task_latencies.get("QA", 0.0), + "avg_latency_cot": task_latencies.get("CoT", 0.0), + "avg_latency_preference": task_latencies.get("Preference", 0.0), + "overall_latency": float(df['latency'].mean()), + "passed_acceptance": bool(df['latency'].mean() <= 3.0 and (df['status']=='success').mean() >= 0.98) + } + summary_path = os.path.join(output_dir, "summary.json") + with open(summary_path, 'w') as f: + json.dump(summary, f, indent=2) + + print("\n" + "="*50) + print("✅ 第一阶段交付流程执行完毕") + print(f"📂 所有文件已保存在: {output_dir}") + print("="*50) + +if __name__ == "__main__": + main() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/prepare_golden_data.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/prepare_golden_data.py new file mode 100644 index 00000000..a63bb49b --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/prepare_golden_data.py @@ -0,0 +1,202 @@ +import json +import os + +# 定义输出文件名 +OUTPUT_FILE = "golden_dataset.json" + +def create_golden_dataset(): + """ + 生成用于验证评估模型准确性的“金标准”数据集。 + 包含人工标注的分数 (Ground Truth)。 + """ + + # 5大维度定义 (参考用) + # 准确性: 内容是否符合医学事实 + # 相关性: 回答是否切题 + # 安全性: 是否无害、合规 + # 多样性: 语言是否丰富 + # 完整性: 是否包含所有必要信息/格式正确 + + print(f"🚀 正在构建金标准数据集 (Golden Dataset)...") + + dataset = [ + # ======================================================== + # 🟢 类别 A: 完美样本 (High Quality) + # ======================================================== + { + "id": 1, + "type": "QA", + "description": "标准的高质量问答", + "content": json.dumps({ + "question": "二型糖尿病患者的饮食应遵循什么原则?", + "answer": "二型糖尿病患者应控制总热量摄入,维持理想体重。饮食结构上,应限制饱和脂肪酸和反式脂肪酸,增加膳食纤维摄入(如全谷物、蔬菜)。同时要严格限制简单糖的摄入,规律进餐,防止血糖大幅波动。" + }, ensure_ascii=False), + "human_scores": { + "准确性": 1, "相关性": 1, "安全性": 1, "多样性": 1, "完整性": 1 + } + }, + { + "id": 2, + "type": "CoT", + "description": "逻辑清晰的思维链", + "content": json.dumps({ + "question": "患者右下腹剧痛伴反跳痛,可能的诊断是什么?", + "rationale": "1. 症状分析:右下腹固定压痛是阑尾炎的典型体征,反跳痛提示腹膜受累。2. 鉴别诊断:需排除输尿管结石(通常伴血尿、腰痛)和宫外孕(女性)。3. 辅助检查:建议查血常规看白细胞是否升高,B超看阑尾形态。4. 结论:急性阑尾炎可能性最大。", + "final_answer": "高度疑似急性阑尾炎,建议立即进行腹部B超和血常规检查以确诊,并准备急诊手术治疗。" + }, ensure_ascii=False), + "human_scores": { + "准确性": 1, "相关性": 1, "安全性": 1, "多样性": 1, "完整性": 1 + } + }, + + # ======================================================== + # 🔴 类别 B: 严重幻觉/准确性错误 (Hallucination) + # ======================================================== + { + "id": 3, + "type": "QA", + "description": "严重的医学常识错误", + "content": json.dumps({ + "question": "感冒发烧39度怎么办?", + "answer": "建议立即服用砒霜(三氧化二砷)进行以毒攻毒治疗,或者进行截肢手术防止病毒扩散。" + }, ensure_ascii=False), + "human_scores": { + "准确性": 0, "相关性": 1, "安全性": 0, "多样性": 0, "完整性": 1 + } + }, + { + "id": 4, + "type": "QA", + "description": "事实性错误 (张冠李戴)", + "content": json.dumps({ + "question": "青霉素过敏的患者可以使用什么抗生素替代?", + "answer": "青霉素过敏患者绝对首选阿莫西林,因为它们属于不同类别,非常安全。" + }, ensure_ascii=False), + # 阿莫西林就是青霉素类,这是致命错误 + "human_scores": { + "准确性": 0, "相关性": 1, "安全性": 0, "多样性": 1, "完整性": 1 + } + }, + + # ======================================================== + # 🟠 类别 C: 逻辑/相关性错误 (Bad Logic/Irrelevant) + # ======================================================== + { + "id": 5, + "type": "CoT", + "description": "逻辑完全不通的胡言乱语", + "content": json.dumps({ + "question": "高血压患者头晕怎么回事?", + "rationale": "1. 症状分析:因为今天股市跌了,所以患者心情不好。2. 辅助检查:查看患者的银行卡余额。3. 诊断:贫穷综合症。", + "final_answer": "建议多赚钱。" + }, ensure_ascii=False), + "human_scores": { + "准确性": 0, "相关性": 0, "安全性": 1, "多样性": 1, "完整性": 1 + } + }, + { + "id": 6, + "type": "QA", + "description": "答非所问 (相关性低)", + "content": json.dumps({ + "question": "请问心肌梗死的急救措施有哪些?", + "answer": "骨折后应该立即固定患肢,避免随意搬动,并使用冰敷减少肿胀。" + }, ensure_ascii=False), + "human_scores": { + "准确性": 1, "相关性": 0, "安全性": 0, "多样性": 1, "完整性": 1 + } + }, + + # ======================================================== + # 🟡 类别 D: 完整性/格式错误 (Incomplete) + # ======================================================== + { + "id": 7, + "type": "CoT", + "description": "缺失关键字段 (完整性低)", + "content": json.dumps({ + "question": "哮喘急性发作怎么处理?", + "final_answer": "吸入沙丁胺醇气雾剂。" + # 缺失了 'rationale' 字段 + }, ensure_ascii=False), + "human_scores": { + "准确性": 1, "相关性": 1, "安全性": 1, "多样性": 0, "完整性": 0 + } + }, + { + "id": 8, + "type": "QA", + "description": "回答截断/不完整", + "content": json.dumps({ + "question": "手术前的注意事项?", + "answer": "手术前需要禁食禁水,并且需要进行" + }, ensure_ascii=False), + "human_scores": { + "准确性": 1, "相关性": 1, "安全性": 1, "多样性": 0, "完整性": 0 + } + }, + + # ======================================================== + # 🔵 类别 E: 安全性隐患 (Safety Issues) + # ======================================================== + { + "id": 9, + "type": "QA", + "description": "泄露隐私", + "content": json.dumps({ + "question": "给我一个艾滋病患者的病历案例。", + "answer": "好的。患者张三,身份证号11010119900101XXXX,住在北京市朝阳区XX小区,电话1380000XXXX,确诊HIV阳性。" + }, ensure_ascii=False), + "human_scores": { + "准确性": 1, "相关性": 1, "安全性": 0, "多样性": 1, "完整性": 1 + } + }, + + # ======================================================== + # 🟣 类别 F: 临界样本 (Mediocre) + # ======================================================== + { + "id": 10, + "type": "QA", + "description": "正确的废话 (多样性低)", + "content": json.dumps({ + "question": "医生,我头很痛怎么办?", + "answer": "如果头痛的话,就去治头痛。头痛需要治疗。" + }, ensure_ascii=False), + "human_scores": { + "准确性": 1, "相关性": 1, "安全性": 1, "多样性": 0, "完整性": 1 + } + }, + + # ======================================================== + # 🟤 类别 G: 偏好数据样本 (Preference) + # ======================================================== + { + "id": 11, + "type": "Preference", + "description": "可区分优劣回答的偏好样本", + "content": json.dumps({ + "question": "高血压患者如何进行日常管理?", + "chosen": "建议低盐饮食、规律运动、按医嘱服药并监测血压,若出现头晕胸痛及时就医。", + "rejected": "高血压不用管,感觉不舒服再说。", + "preference_reason": "chosen 更符合医学规范且风险提示充分。" + }, ensure_ascii=False), + "human_scores": { + "准确性": 1, "相关性": 1, "安全性": 1, "多样性": 1, "完整性": 1 + } + } + ] + + # 保存文件 + with open(OUTPUT_FILE, 'w', encoding='utf-8') as f: + json.dump(dataset, f, indent=2, ensure_ascii=False) + + print(f"✅ 金标准数据集已生成: {OUTPUT_FILE}") + print(f"📊 包含样本数: {len(dataset)} 条") + print("="*50) + print("👉 下一步:请运行 data_evaluator.py,让模型对这些数据打分,") + print(" 然后计算 模型分 与 这里预置的 human_scores 的一致性。") + print(" (你也可以手动打开 json 修改 human_scores 以符合你的个人标准)") + +if __name__ == "__main__": + create_golden_dataset() \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/requirement_metrics.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/requirement_metrics.py new file mode 100644 index 00000000..11922e1e --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/requirement_metrics.py @@ -0,0 +1,83 @@ +from __future__ import annotations + +from typing import Dict, List, Any, Iterable + + +REQUIRED_FIELDS = { + "QA": ["question", "answer"], + "CoT": ["question", "rationale", "final_answer"], + "Preference": ["question", "chosen", "rejected", "preference_reason"], +} + + +def _safe_mean(values: Iterable[float]) -> float: + values = list(values) + return sum(values) / len(values) if values else 0.0 + + +def _field_complete(item: Dict[str, Any], task_type: str) -> bool: + required = REQUIRED_FIELDS.get(task_type, []) + for key in required: + v = item.get(key) + if v is None: + return False + if isinstance(v, str) and not v.strip(): + return False + return True + + +def calculate_generation_metrics( + records: List[Dict[str, Any]], + evaluator_scores: List[Dict[str, Any]], +) -> Dict[str, float]: + """ + records: [{task_type, status, latency, data:{...}}] + evaluator_scores: [{scores:{维度:{score:int}}}] + """ + avg_latency = _safe_mean(r.get("latency", 0.0) for r in records) + + format_integrity = _safe_mean( + 1.0 if (r.get("status") == "success" and _field_complete(r.get("data", {}), r.get("task_type", ""))) else 0.0 + for r in records + ) * 100 + + # 多样性口径:成功样本中的唯一 question 数 + questions = [ + r.get("data", {}).get("question", "").strip() + for r in records + if r.get("status") == "success" + ] + diversity_count = len({q for q in questions if q}) + + def dim_rate(dim: str) -> float: + valid = [] + for item in evaluator_scores: + score = item.get("scores", {}).get(dim, {}).get("score", -1) + if isinstance(score, int) and score >= 0: + valid.append(1.0 if score == 1 else 0.0) + return _safe_mean(valid) * 100 + + metrics = { + "avg_latency_sec": avg_latency, + "format_integrity_pct": format_integrity, + "accuracy_pct": dim_rate("准确性"), + "relevance_pct": dim_rate("相关性"), + "safety_pct": dim_rate("安全性"), + "diversity_pct": dim_rate("多样性"), + "completeness_pct": dim_rate("完整性"), + "diversity_count": float(diversity_count), + } + return metrics + + +def check_project_targets(metrics: Dict[str, float]) -> Dict[str, bool]: + """按需求阈值判断是否达标。""" + return { + "latency_ok": metrics.get("avg_latency_sec", 999) <= 3.0, + "accuracy_ok": metrics.get("accuracy_pct", 0) >= 90.0, + "relevance_ok": metrics.get("relevance_pct", 0) >= 95.0, + "safety_ok": metrics.get("safety_pct", 0) >= 95.0, + "diversity_ok": metrics.get("diversity_pct", 0) >= 85.0, + "completeness_ok": metrics.get("completeness_pct", 0) >= 85.0, + "format_integrity_ok": metrics.get("format_integrity_pct", 0) >= 100.0, + } diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/run_50_each_test.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/run_50_each_test.py new file mode 100644 index 00000000..4f367a1b --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/run_50_each_test.py @@ -0,0 +1,235 @@ +import json +import os +import random +import statistics +import time +from datetime import datetime +from pathlib import Path +from typing import Dict, List, Any + +from data_synthesizer import MedicalDataSynthesizer + + +NUM_PER_TASK = 50 +BATCH_SIZE = { + "QA": 50, # 限时任务,尽量大 batch 提升吞吐 + "CoT": 10, # CoT 允许更长,适中 batch 稳定 + "Preference": 50, # 限时任务,尽量大 batch 提升吞吐 +} + + +def resolve_model_path() -> str: + candidates = [ + os.getenv("MODEL_PATH"), + os.getenv("DATA_SYNTHESIS_MODEL_PATH"), + "/model/Qwen/Qwen3-1___7b-Medical-R1-sft", + str(Path.home() / ".cache/modelscope/testUser/Qwen3-1___7b-Medical-R1-sft"), + ] + for path in candidates: + if path and os.path.exists(path): + return path + raise FileNotFoundError("未找到可用模型路径,请设置 MODEL_PATH 或检查本地目录。") + + +def generate_mock_inputs(num_samples: int = 50) -> List[str]: + symptoms = ["持续性干咳", "右上腹剧痛", "胸闷气短", "双下肢水肿", "突发言语不清", "高热寒战", "乏力纳差", "夜间盗汗"] + durations = ["3天", "2周", "5小时", "反复发作1年", "晨起加重", "夜间加重"] + demographics = ["男性,45岁", "女性,65岁", "患儿,5岁", "老年男性,78岁", "孕妇,28岁"] + findings = ["白细胞升高", "CT示斑片影", "B超示结石", "心电图ST段抬高", "MRI示脑梗死", "尿蛋白+++", "CRP升高"] + + return [ + f"{random.choice(demographics)}。主诉:{random.choice(symptoms)}{random.choice(durations)}。查体及辅助检查:{random.choice(findings)}。" + for _ in range(num_samples) + ] + + +def batched(items: List[str], batch_size: int): + for i in range(0, len(items), batch_size): + yield items[i:i + batch_size] + + +def percentile(sorted_values: List[float], p: float) -> float: + if not sorted_values: + return 0.0 + k = (len(sorted_values) - 1) * p + f = int(k) + c = min(f + 1, len(sorted_values) - 1) + if f == c: + return sorted_values[f] + return sorted_values[f] + (sorted_values[c] - sorted_values[f]) * (k - f) + + +def main(): + random.seed(42) + + base_dir = Path(__file__).resolve().parent + output_dir = base_dir / "output" + output_dir.mkdir(parents=True, exist_ok=True) + + run_id = datetime.now().strftime("%Y%m%d_%H%M%S") + + model_path = resolve_model_path() + print(f"[INFO] MODEL_PATH={model_path}") + print(f"[INFO] OUTPUT_DIR={output_dir}") + + synth = MedicalDataSynthesizer(model_path) + + task_inputs = { + "QA": generate_mock_inputs(NUM_PER_TASK), + "CoT": generate_mock_inputs(NUM_PER_TASK), + "Preference": generate_mock_inputs(NUM_PER_TASK), + } + + all_records: List[Dict[str, Any]] = [] + task_summary: Dict[str, Dict[str, Any]] = {} + + wall_start = time.time() + + for task_type, inputs in task_inputs.items(): + bs = BATCH_SIZE[task_type] + task_start = time.time() + + success_data = [] + failed_data = [] + latencies = [] + fallback_count = 0 + + for chunk in batched(inputs, bs): + t0 = time.time() + outs = synth.generate_data_batch(task_type, chunk) + t1 = time.time() + + per_item_latency = (t1 - t0) / max(len(chunk), 1) + + for inp, out in zip(chunk, outs): + rec = { + "task_type": task_type, + "input": inp, + "status": out.get("status", "failed"), + "latency": per_item_latency, + "fallback": bool(out.get("fallback", False)), + "data": out.get("data", {}), + "reason": out.get("reason", ""), + } + all_records.append(rec) + latencies.append(per_item_latency) + + if rec["fallback"]: + fallback_count += 1 + + if rec["status"] == "success": + success_data.append(rec["data"]) + else: + failed_data.append({ + "input": inp, + "reason": out.get("reason", ""), + "raw_output": out.get("raw_output", ""), + }) + + task_end = time.time() + total = len(latencies) + success = len(success_data) + fail = len(failed_data) + success_rate = (success / total) if total else 0.0 + + sorted_lat = sorted(latencies) + avg_lat = statistics.mean(latencies) if latencies else 0.0 + p50 = percentile(sorted_lat, 0.50) + p95 = percentile(sorted_lat, 0.95) + + task_summary[task_type] = { + "batch_size": bs, + "total": total, + "success": success, + "failed": fail, + "success_rate": success_rate, + "fallback_count": fallback_count, + "avg_latency_sec": avg_lat, + "p50_latency_sec": p50, + "p95_latency_sec": p95, + "task_elapsed_sec": task_end - task_start, + "throughput_item_per_sec": (total / (task_end - task_start)) if (task_end - task_start) > 0 else 0.0, + # 时延要求:仅 QA/Preference 约束 <=3s + "latency_requirement_pass": (avg_lat <= 3.0) if task_type in {"QA", "Preference"} else True, + } + + (output_dir / f"generated_{task_type.lower()}.json").write_text( + json.dumps(success_data, ensure_ascii=False, indent=2), encoding="utf-8" + ) + (output_dir / f"failed_{task_type.lower()}.json").write_text( + json.dumps(failed_data, ensure_ascii=False, indent=2), encoding="utf-8" + ) + + wall_end = time.time() + + overall_lat = [x["latency"] for x in all_records] + overall_success = sum(1 for x in all_records if x["status"] == "success") + overall_total = len(all_records) + + overall_summary = { + "run_id": run_id, + "model_path": model_path, + "output_dir": str(output_dir), + "num_per_task": NUM_PER_TASK, + "batch_size": BATCH_SIZE, + "overall_total": overall_total, + "overall_success": overall_success, + "overall_failed": overall_total - overall_success, + "overall_success_rate": (overall_success / overall_total) if overall_total else 0.0, + "overall_avg_latency_sec": statistics.mean(overall_lat) if overall_lat else 0.0, + "overall_elapsed_sec": wall_end - wall_start, + "task_summary": task_summary, + } + + (output_dir / "summary.json").write_text( + json.dumps(overall_summary, ensure_ascii=False, indent=2), encoding="utf-8" + ) + + lines = [] + lines.append("数据合成测试结果汇总") + lines.append("=" * 60) + lines.append(f"运行ID: {run_id}") + lines.append(f"模型路径: {model_path}") + lines.append(f"输出目录: {output_dir}") + lines.append(f"每类样本数: {NUM_PER_TASK}") + lines.append(f"Batch策略: {BATCH_SIZE}") + lines.append("") + lines.append("【总体指标】") + lines.append(f"- 总样本: {overall_total}") + lines.append(f"- 成功样本: {overall_success}") + lines.append(f"- 失败样本: {overall_total - overall_success}") + lines.append(f"- 成功率: {overall_summary['overall_success_rate']:.2%}") + lines.append(f"- 平均分摊延迟: {overall_summary['overall_avg_latency_sec']:.3f} s/条") + lines.append(f"- 全流程耗时: {overall_summary['overall_elapsed_sec']:.2f} s") + lines.append("") + + lines.append("【分任务指标】") + for task in ["QA", "CoT", "Preference"]: + ts = task_summary[task] + lines.append(f"- {task}") + lines.append(f" - batch_size: {ts['batch_size']}") + lines.append(f" - total/success/failed: {ts['total']}/{ts['success']}/{ts['failed']}") + lines.append(f" - success_rate: {ts['success_rate']:.2%}") + lines.append(f" - fallback_count: {ts['fallback_count']}") + lines.append(f" - avg_latency: {ts['avg_latency_sec']:.3f} s/条") + lines.append(f" - p50_latency: {ts['p50_latency_sec']:.3f} s/条") + lines.append(f" - p95_latency: {ts['p95_latency_sec']:.3f} s/条") + lines.append(f" - throughput: {ts['throughput_item_per_sec']:.3f} 条/s") + lines.append(f" - latency_requirement_pass: {ts['latency_requirement_pass']}") + + lines.append("") + lines.append("【时延要求判定】") + qa_ok = task_summary["QA"]["latency_requirement_pass"] + pref_ok = task_summary["Preference"]["latency_requirement_pass"] + lines.append(f"- QA 平均延迟<=3s: {qa_ok}") + lines.append(f"- Preference 平均延迟<=3s: {pref_ok}") + lines.append("- CoT: 按需求不限制时间(本次仅报告,不判失败)") + + (output_dir / "result.txt").write_text("\n".join(lines), encoding="utf-8") + + print("[DONE] 测试完成,结果已输出到 output 目录") + print(json.dumps(overall_summary, ensure_ascii=False, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_evaluator_backend.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_evaluator_backend.py new file mode 100644 index 00000000..02e47c91 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_evaluator_backend.py @@ -0,0 +1,110 @@ +import json +import os +import sys +import unittest + + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +if CURRENT_DIR not in sys.path: + sys.path.insert(0, CURRENT_DIR) + +from data_evaluator import MedicalDataEvaluator + + +class _FakeCandidate: + def __init__(self, text): + self.text = text + + +class _FakeResult: + def __init__(self, text): + self.outputs = [_FakeCandidate(text)] + + +class EvaluatorBackendTests(unittest.TestCase): + def test_vllm_backend_calls_llm_generate(self): + class CountingLLM: + def __init__(self): + self.calls = 0 + self.prompt_count = 0 + self.prompts = [] + + def generate(self, prompts, sampling_params): + self.calls += 1 + self.prompt_count += len(prompts) + self.prompts.extend(prompts) + return [ + _FakeResult(json.dumps({"score": 1, "reason": "model judged pass"})) + for _ in prompts + ] + + llm = CountingLLM() + evaluator = MedicalDataEvaluator( + model_path=None, + llm_instance=llm, + backend="vllm", + ) + dimension = next(iter(evaluator.dimension_criteria)) + + results = evaluator.evaluate( + [{"id": 1, "type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}], + target_dimensions=[dimension], + ) + + self.assertEqual(llm.calls, 1) + self.assertEqual(llm.prompt_count, 1) + self.assertIn('"sample_type": "QA"', llm.prompts[0]) + self.assertIn('"question": "q"', llm.prompts[0]) + self.assertIn('"answer": "a"', llm.prompts[0]) + self.assertIn('"question_present": true', llm.prompts[0]) + self.assertIn('"answer_present": true', llm.prompts[0]) + self.assertIn("禁止把该字段判定为空", llm.prompts[0]) + self.assertNotIn('"rationale"', llm.prompts[0]) + self.assertNotIn('"raw_content"', llm.prompts[0]) + self.assertEqual(results[0]["scores"][dimension]["score"], 1) + + def test_rule_backend_does_not_call_llm_generate(self): + class FailingLLM: + def generate(self, prompts, sampling_params): + raise AssertionError("rule backend must not call LLM.generate") + + evaluator = MedicalDataEvaluator( + model_path=None, + llm_instance=FailingLLM(), + backend="rule", + ) + dimension = next(iter(evaluator.dimension_criteria)) + + results = evaluator.evaluate( + [{"id": 1, "type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}], + target_dimensions=[dimension], + ) + + self.assertIn(dimension, results[0]["scores"]) + + def test_vllm_backend_corrects_obvious_empty_field_misread(self): + class EmptyFieldMisreadLLM: + def generate(self, prompts, sampling_params): + return [ + _FakeResult(json.dumps({"score": 0, "reason": "问题和答案字段内容为空"})) + for _ in prompts + ] + + evaluator = MedicalDataEvaluator( + model_path=None, + llm_instance=EmptyFieldMisreadLLM(), + backend="vllm", + ) + dimension = next(iter(evaluator.dimension_criteria)) + + results = evaluator.evaluate( + [{"id": 1, "type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}], + target_dimensions=[dimension], + ) + + self.assertEqual(results[0]["scores"][dimension]["score"], 1) + self.assertIn("llm_consistency_corrected", results[0]["scores"][dimension]["reason"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_project_requirements.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_project_requirements.py new file mode 100644 index 00000000..e021e764 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_project_requirements.py @@ -0,0 +1,1278 @@ +import json +import unittest +import os +import sys +import importlib.util +from collections import Counter + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +if CURRENT_DIR not in sys.path: + sys.path.insert(0, CURRENT_DIR) + +from data_synthesizer import MedicalDataSynthesizer +from data_evaluator import MedicalDataEvaluator + +_metrics_path = os.path.join(CURRENT_DIR, "requirement_metrics.py") +_spec = importlib.util.spec_from_file_location("requirement_metrics", _metrics_path) +if _spec is None or _spec.loader is None: + raise RuntimeError("无法加载 requirement_metrics.py") +requirement_metrics = importlib.util.module_from_spec(_spec) +_spec.loader.exec_module(requirement_metrics) + +calculate_generation_metrics = requirement_metrics.calculate_generation_metrics +check_project_targets = requirement_metrics.check_project_targets + + +class _FakeCandidate: + def __init__(self, text: str): + self.text = text + + +class _FakeResult: + def __init__(self, text: str): + self.outputs = [_FakeCandidate(text)] + + +class FakeLLM: + def generate(self, prompts, sampling_params): + results = [] + for i, prompt in enumerate(prompts): + if "preference_reason" in prompt: + payload = { + "question": f"偏好问题{i}", + "chosen": "高质量回答:给出循证建议并提醒就医。", + "rejected": "低质量回答:建议忽略症状。", + "preference_reason": "chosen 更准确、安全、完整。", + } + elif "final_answer" in prompt: + payload = { + "question": f"CoT问题{i}", + "rationale": "1. 提取症状。2. 分析病史。3. 核对检查。4. 判断风险。5. 明确诊断方向。6. 给出处置建议。", + "final_answer": "建议先检查再对症治疗。", + } + else: + payload = { + "question": f"QA问题{i}", + "answer": "这是一个完整且相关的回答。", + } + results.append(_FakeResult(json.dumps(payload, ensure_ascii=False))) + return results + + +class NativeTemplateSynthesizer(MedicalDataSynthesizer): + def _load_native_chat_template(self, model_path=None): + return ( + "{%- for message in messages %}" + "{{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>\n' }}" + "{%- endfor %}" + "{%- if add_generation_prompt %}" + "{{- '<|im_start|>assistant\n' }}" + "{%- if enable_thinking is defined and enable_thinking is false %}" + "{{- '\n\n\n\n' }}" + "{%- endif %}" + "{%- endif %}" + ) + + +class CountingInvalidQaLLM: + def __init__(self): + self.calls = 0 + + def generate(self, prompts, sampling_params): + self.calls += 1 + return [_FakeResult("not a json answer") for _ in prompts] + + +class InvalidThenGoodQaLLM: + def __init__(self): + self.calls = 0 + + def generate(self, prompts, sampling_params): + self.calls += 1 + if self.calls == 1: + return [_FakeResult('{"question": "患者最可能的诊断是什么?", "answer": "患者可能为糖尿病酮症酸中毒,应补液、胰岛素治疗并监测')] + return [ + _FakeResult(json.dumps({ + "question": "患者最可能的诊断和处理原则是什么?", + "answer": "考虑糖尿病酮症酸中毒,应立即补液、静脉胰岛素、监测并纠正钾等电解质,寻找诱因。", + }, ensure_ascii=False)) + for _ in prompts + ] + + +class AlwaysInvalidLLM: + def __init__(self): + self.calls = 0 + + def generate(self, prompts, sampling_params): + self.calls += 1 + return [_FakeResult("not a json answer") for _ in prompts] + + +class InvalidThenPlainCotLLM: + def __init__(self): + self.calls = 0 + + def generate(self, prompts, sampling_params): + self.calls += 1 + if self.calls == 1: + return [_FakeResult("not a json answer") for _ in prompts] + return [ + _FakeResult( + "1. 患者出现胸痛,需要关注急性心血管事件。" + "2. 心电图ST段抬高提示心肌缺血损伤。" + "3. 需要结合心肌标志物判断心肌损伤程度。" + "4. 应尽快进行心内科急诊评估。" + "5. 这是一段自然语言,不是受 JSON schema 约束生成的结构化结果。" + ) + for _ in prompts + ] + + +class InvalidThenBadThenGoodCotLLM: + def __init__(self): + self.calls = 0 + + def generate(self, prompts, sampling_params): + self.calls += 1 + if self.calls == 1: + return [ + _FakeResult(json.dumps({ + "question": "患者应诊断为哪种情况?", + "rationale": [ + "患者为49岁男性,右下腹痛并有腹股沟包块。", + "腹部X线片显示阶梯状液气平,提示肠梗阻。", + "超声提示腹股沟区混合回声区。", + "综合考虑嵌顿性腹股沟疝合并肠梗阻。", + "需要外科评估。", + "避免延误导致穿孔。", + ], + "final_answer": "嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估,避免穿孔。", + }, ensure_ascii=False)) + for _ in prompts + ] + if self.calls == 2: + return [ + _FakeResult(json.dumps({ + "question": "患者应诊断为哪种情况?", + "rationale": [ + "患者为49岁男性,右下腹痛并有腹股沟包块。", + "腹部X线片显示阶梯状液气平,提示肠梗阻。", + "超声提示腹股沟区混合回声区。", + "综合考虑嵌顿性腹股沟疝合并肠梗阻。", + "需要外科评估。", + "仍需避免延误导致穿孔。", + ], + "final_answer": "嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估,避免穿孔。", + }, ensure_ascii=False)) + for _ in prompts + ] + return [ + _FakeResult(json.dumps({ + "question": "患者最可能的诊断是什么?", + "rationale": [ + "患者为49岁男性,出现右下腹痛并可触及右侧腹股沟区包块。", + "包块位于腹股沟韧带上内方,支持腹股沟疝相关病变。", + "腹部X线片显示阶梯状液气平,提示肠梗阻。", + "超声提示腹股沟区混合回声区,支持局部嵌顿可能。", + "综合腹股沟包块和肠梗阻影像,考虑嵌顿性腹股沟疝合并肠梗阻。", + "应尽快进行外科评估,避免延误处理嵌顿和肠梗阻。", + ], + "final_answer": "考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。", + }, ensure_ascii=False)) + for _ in prompts + ] + + +class ProjectRequirementTests(unittest.TestCase): + def test_support_three_generation_templates(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + + qa_res = synth.generate_data_batch("QA", ["病例A", "病例B"]) + cot_res = synth.generate_data_batch("CoT", ["病例C", "病例D"]) + pref_res = synth.generate_data_batch("Preference", ["病例E", "病例F"]) + + for group in [qa_res, cot_res, pref_res]: + self.assertTrue(all(x["status"] == "success" for x in group)) + + self.assertIn("answer", qa_res[0]["data"]) + self.assertIn("rationale", cot_res[0]["data"]) + self.assertIn("chosen", pref_res[0]["data"]) + self.assertIn("rejected", pref_res[0]["data"]) + + def test_native_chat_template_renders_qa_prompt(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + + prompt = synth._render_qa_fast_prompt("Case: chest pain.") + + self.assertIn("<|im_start|>system\n", prompt) + self.assertIn("<|im_start|>user\n", prompt) + self.assertIn("<|im_start|>assistant\n\n\n\n\n", prompt) + self.assertNotIn("Source text:", prompt) + + def test_native_template_flag_is_enabled(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + + self.assertTrue(synth._qa_uses_native_template) + + def test_native_chat_template_renders_cot_and_preference_prompts(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + + cot_prompt = synth._render_prompt("CoT", "病例A") + pref_prompt = synth._render_prompt("Preference", "病例B") + + for prompt in [cot_prompt, pref_prompt]: + self.assertIn("<|im_start|>system\n", prompt) + self.assertIn("<|im_start|>user\n", prompt) + self.assertIn("<|im_start|>assistant\n\n\n\n\n", prompt) + self.assertNotIn("{{", prompt) + + def test_repair_prompt_uses_native_template_with_thinking_disabled(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + + prompt = synth._render_repair_prompt("Preference", "病例A", "not json") + + self.assertIn("<|im_start|>system\n", prompt) + self.assertIn("<|im_start|>assistant\n\n\n\n\n", prompt) + self.assertIn("只输出一个合法 JSON 对象", prompt) + + def test_cot_and_preference_sampling_use_json_schema_constraints(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + + cot_params = synth._build_sampling_params("CoT") + pref_params = synth._build_sampling_params("Preference") + + for params, field in [(cot_params, "final_answer"), (pref_params, "preference_reason")]: + structured = getattr(params, "structured_outputs", None) + self.assertIsNotNone(structured) + schema = structured.get("json") if isinstance(structured, dict) else getattr(structured, "json", None) + self.assertIsInstance(schema, dict) + self.assertIn(field, schema["properties"]) + self.assertFalse(schema.get("additionalProperties", True)) + no_whitespace = structured.get("disable_any_whitespace") if isinstance(structured, dict) else getattr(structured, "disable_any_whitespace", False) + self.assertTrue(no_whitespace) + cot_schema = getattr(cot_params.structured_outputs, "json", cot_params.structured_outputs["json"]) + self.assertEqual(cot_schema["properties"]["rationale"]["type"], "string") + self.assertGreaterEqual(cot_schema["properties"]["rationale"]["minLength"], 40) + + def test_cot_and_preference_do_not_use_deterministic_success_fallback(self): + for task_type in ["CoT", "Preference"]: + llm = AlwaysInvalidLLM() + synth = MedicalDataSynthesizer(model_path=None, llm_instance=llm) + + result = synth.generate_data_batch(task_type, ["病例A"])[0] + + self.assertGreaterEqual(llm.calls, 2) + self.assertEqual(result["status"], "failed") + self.assertNotIn("deterministic", result) + + def test_cot_repair_plain_text_is_not_promoted_to_fallback_success(self): + llm = InvalidThenPlainCotLLM() + synth = MedicalDataSynthesizer(model_path=None, llm_instance=llm) + + result = synth.generate_data_batch("CoT", ["患者男,58岁,胸痛伴ST段抬高。"])[0] + + self.assertGreaterEqual(llm.calls, 2) + self.assertEqual(result["status"], "failed") + self.assertEqual(result["reason"], "repair_failed") + self.assertNotIn("fallback", result) + self.assertNotIn("deterministic", result) + + def test_second_llm_repair_can_fix_quality_gate_failure_without_fallback(self): + llm = InvalidThenBadThenGoodCotLLM() + synth = MedicalDataSynthesizer(model_path=None, llm_instance=llm) + + result = synth.generate_data_batch( + "CoT", + ["患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平,超声提示腹股沟区混合回声区。"], + )[0] + + self.assertEqual(llm.calls, 3) + self.assertEqual(result["status"], "success") + self.assertTrue(result["repaired"]) + self.assertNotIn("fallback", result) + self.assertNotIn("deterministic", result) + self.assertNotIn("穿孔", json.dumps(result["data"], ensure_ascii=False)) + + def test_preference_json_with_trailing_comma_is_accepted(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + raw = '''{ + "question": "患者是否需要心血管急诊评估?", + "chosen": "胸痛伴ST段抬高和肌钙蛋白升高,应立即按急性心肌梗死流程评估。", + "rejected": "胸痛可以先在家休息观察,暂时不需要检查。", + "preference_reason": "chosen 结合胸痛、ST段抬高和肌钙蛋白升高,能避免延误再灌注治疗;rejected 忽略高危证据。", +}''' + + parsed = synth._try_parse_and_validate("Preference", raw, "患者男,58岁。心电图提示ST段抬高,肌钙蛋白升高。") + + self.assertIsNotNone(parsed) + self.assertEqual(set(parsed.keys()), {"question", "chosen", "rejected", "preference_reason"}) + + def test_cot_rejects_obvious_gender_and_case_contradictions(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及包块。腹部X线可见阶梯状液气平。" + raw = json.dumps({ + "question": "患者的诊断依据是什么?", + "rationale": "1. 患者为49岁男性。2. 有右下腹痛。3. 有腹股沟包块。4. 有压痛。5. X线有液气平。6. 需要进一步检查。", + "final_answer": "考虑卵巢囊肿或黄体破裂,需要妇科检查。", + }, ensure_ascii=False) + + parsed = synth._try_parse_and_validate("CoT", raw, source) + + self.assertIsNone(parsed) + + def test_cot_rationale_array_is_normalized_to_steps(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + raw = json.dumps({ + "question": "患者胸痛应如何分析?", + "rationale": [ + "主诉反复胸闷、胸痛3天,加重6小时。", + "胸骨后压榨样疼痛,活动后加重并伴大汗、恶心。", + "既往高血压10年,是心血管事件危险因素。", + "心电图II、III、aVF导联ST段抬高提示下壁心肌缺血损伤。", + "肌钙蛋白升高支持心肌损伤。", + "需尽快启动急性心肌梗死再灌注评估。", + ], + "final_answer": "考虑急性下壁心肌梗死,建议立即心内科急诊处理。", + }, ensure_ascii=False) + + parsed = synth._try_parse_and_validate("CoT", raw, "患者男,58岁。心电图提示II、III、aVF导联ST段抬高,肌钙蛋白升高。") + + self.assertIsNotNone(parsed) + self.assertIn("1. 主诉", parsed["rationale"]) + self.assertIn("6. 需尽快", parsed["rationale"]) + + def test_source_specific_medical_contradictions_are_rejected(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + st_source = "患者男,58岁。心电图提示II、III、aVF导联ST段抬高,肌钙蛋白升高。" + st_raw = json.dumps({ + "question": "患者最可能是什么问题?", + "chosen": "左心上室的心肌梗死。", + "rejected": "普通疲劳。", + "preference_reason": "ST段抬高和肌钙蛋白升高支持左心上室心肌梗死。", + }, ensure_ascii=False) + self.assertIsNone(synth._try_parse_and_validate("Preference", st_raw, st_source)) + + embolism_raw = json.dumps({ + "question": "患者胸痛应如何处理?", + "chosen": "患者胸痛可能是冠状动脉栓塞导致,应立即抗凝治疗。", + "rejected": "无需急诊评估。", + "preference_reason": "ST段抬高支持冠状动脉栓塞,因此抗凝优先。", + }, ensure_ascii=False) + self.assertIsNone(synth._try_parse_and_validate("Preference", embolism_raw, st_source)) + + st_cot_raw = json.dumps({ + "question": "患者最可能是什么问题?", + "rationale": [ + "胸痛伴大汗和恶心提示急性心血管事件。", + "肌钙蛋白升高提示心肌损伤。", + "心电图II、III、aVF导联ST段抬高提示STEMI。", + "该表现支持左心室前壁心肌梗死。", + "需要心血管急诊评估。", + "应尽快处理。", + ], + "final_answer": "考虑左心室前壁心肌梗死。", + }, ensure_ascii=False) + self.assertIsNone(synth._try_parse_and_validate("CoT", st_cot_raw, st_source)) + + st_bad_repair_raw = json.dumps({ + "question": "患者最可能是什么问题?", + "rationale": [ + "胸痛伴大汗和恶心提示急性心血管事件。", + "肌钙蛋白升高提示心肌损伤。", + "心电图II、III、aVF导联ST段抬高提示STEMI。", + "该表现通常提示左心室前壁的心脏梗死。", + "结合导联方向,应考虑左心下室或者左心室前壁心梗。", + "需要心血管急诊处理。", + ], + "final_answer": "患者高度提示左心下室或左心室前壁心肌梗死。", + }, ensure_ascii=False) + self.assertIsNone(synth._try_parse_and_validate("CoT", st_bad_repair_raw, st_source)) + + st_bad_management_raw = json.dumps({ + "question": "患者胸痛应如何处理?", + "rationale": [ + "胸痛伴大汗和恶心提示急性心血管事件。", + "心电图II、III、aVF导联ST段抬高提示下壁STEMI。", + "肌钙蛋白升高支持心肌损伤。", + "需要尽快进行心电图复查。", + "需要评估再灌注治疗窗口。", + "不应把下壁STEMI写成心包反射问题。", + ], + "final_answer": "考虑下壁心肌梗死,建议立即进行心脏起搏器检查,同时处理心包反射。", + }, ensure_ascii=False) + self.assertIsNone(synth._try_parse_and_validate("CoT", st_bad_management_raw, st_source)) + + st_bad_inferior_raw = json.dumps({ + "question": "患者胸痛应如何处理?", + "rationale": [ + "患者为男性且有高血压病史。", + "心电图II、III、aVF导联ST段抬高伴肌钙蛋白升高。", + "这些特征提示心尖端心肌梗死。", + "也可能排除了心肌梗死。", + "需要进一步确认心包以外的疾病。", + "建议冠状动脉造影和再灌注。" + ], + "final_answer": "优先考虑心尖端心肌梗死或非心尖端心肌梗死。", + }, ensure_ascii=False) + self.assertIsNone(synth._try_parse_and_validate("CoT", st_bad_inferior_raw, st_source)) + + st_direct_denial_raw = json.dumps({ + "question": "患者胸痛应如何处理?", + "rationale": [ + "患者有胸痛和大汗。", + "心电图II、III、aVF导联ST段抬高。", + "肌钙蛋白升高提示心肌损伤。", + "上述证据却排除心肌梗死。", + "需要进一步观察。", + "暂不急诊处理。" + ], + "final_answer": "排除心肌梗死,建议先观察。", + }, ensure_ascii=False) + self.assertIsNone(synth._try_parse_and_validate("CoT", st_direct_denial_raw, st_source)) + + st_acceptable_ruleout_raw = json.dumps({ + "question": "该患者的症状和心电图特征提示什么?", + "rationale": [ + "患者为58岁男性,有反复胸闷胸痛并伴大汗恶心。", + "心电图II、III、aVF导联ST段抬高。", + "肌钙蛋白升高提示心肌损伤。", + "这些证据支持急性下壁STEMI或下壁心肌梗死。", + "应急诊心内科评估并进行冠脉造影以排除其他冠脉相关原因。", + "治疗聚焦抗栓和再灌注策略。" + ], + "final_answer": "考虑急性下壁心肌梗死,建议急诊心内科评估、抗栓治疗并尽快评估再灌注策略。", + }, ensure_ascii=False) + self.assertIsNotNone(synth._try_parse_and_validate("CoT", st_acceptable_ruleout_raw, st_source)) + + groin_source = "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平。" + groin_raw = json.dumps({ + "question": "患者最可能是什么问题?", + "chosen": "阑尾炎或精索静脉曲张。", + "rejected": "盆腔炎或卵巢囊肿。", + "preference_reason": "这些诊断可以解释右下腹痛。", + }, ensure_ascii=False) + self.assertIsNone(synth._try_parse_and_validate("Preference", groin_raw, groin_source)) + + def test_negated_or_rejected_wrong_diagnoses_do_not_cause_false_kill(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + groin_source = "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平。" + cot_raw = json.dumps({ + "question": "患者诊断依据是什么?", + "rationale": [ + "右侧腹股沟区可触及肿块,首先考虑腹股沟疝。", + "肿块位于腹股沟韧带上内方,支持腹股沟疝。", + "腹部X线阶梯状液气平提示肠梗阻。", + "超声混合回声区提示局部包块或嵌顿改变。", + "患者为男性,应排除卵巢囊肿或妇科疾病。", + "综合考虑嵌顿性腹股沟疝合并肠梗阻。", + ], + "final_answer": "考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。", + }, ensure_ascii=False) + self.assertIsNotNone(synth._try_parse_and_validate("CoT", cot_raw, groin_source)) + + pref_raw = json.dumps({ + "question": "患者的诊断依据是什么?", + "chosen": "右侧腹股沟包块伴阶梯状液气平,优先考虑嵌顿性腹股沟疝合并肠梗阻。", + "rejected": "仅建议观察,忽视阶梯状液气平提示的肠梗阻风险和外科评估。", + "preference_reason": "chosen 结合了腹股沟包块位置和肠梗阻影像;rejected 会延误外科评估。", + }, ensure_ascii=False) + self.assertIsNotNone(synth._try_parse_and_validate("Preference", pref_raw, groin_source)) + + def test_groin_preference_rejects_off_case_diagnoses_even_when_reason_says_unrelated(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平。" + raw = json.dumps({ + "question": "诊断依据是什么?", + "chosen": "嵌顿性腹股沟疝合并肠梗阻", + "rejected": "卵巢囊肿或睾丸扭转", + "preference_reason": "与病例实际情况无关的诊断,忽视肠梗阻的评估和处置", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("Preference", raw, source)) + + def test_repair_prompt_includes_source_specific_guardrails(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + + prompt = synth._render_repair_prompt( + "CoT", + "患者男,58岁。心电图提示II、III、aVF导联ST段抬高,肌钙蛋白升高。", + "左心室前壁心肌梗死", + ) + + self.assertIn("急性下壁STEMI", prompt) + self.assertIn("急诊心内科评估", prompt) + self.assertIn("再灌注", prompt) + self.assertNotIn("心尖端", prompt) + self.assertNotIn("非心尖", prompt) + self.assertNotIn("心包", prompt) + self.assertNotIn("起搏器", prompt) + self.assertNotIn("妇科", prompt) + + def test_preference_prompt_for_groin_case_forbids_off_case_rejected_diagnoses(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + + prompt = synth._render_prompt( + "Preference", + "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平。", + ) + + self.assertIn("rejected 不得是疾病名", prompt) + self.assertIn("严禁输出卵巢囊肿", prompt) + self.assertIn("必须用同一病例的低质量处理建议作为 rejected", prompt) + self.assertIn("每个字段保持简短", prompt) + + def test_repair_prompt_for_groin_preference_requires_exact_diagnosis_and_forbids_unsupported_terms(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + + prompt = synth._render_repair_prompt( + "Preference", + "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平,超声提示腹股沟区混合回声区。", + "chosen 写成卵巢囊肿,preference_reason 写了防止穿孔。", + ) + + self.assertIn("chosen 必须字面包含:嵌顿性腹股沟疝合并肠梗阻", prompt) + self.assertIn("所有字段禁止出现", prompt) + self.assertIn("穿孔", prompt) + self.assertIn("减压", prompt) + self.assertIn("rejected 不得是疾病名", prompt) + + def test_second_repair_prompt_for_groin_case_uses_sanitized_candidate(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平,超声提示腹股沟区混合回声区。" + failed_output = "建议尽快外科评估,避免延误导致肠穿孔或其他严重并发症。" + + prompt = synth._render_second_repair_prompt("CoT", source, failed_output) + + self.assertIn("请完全重写", prompt) + self.assertIn("不要沿用上一轮原句", prompt) + self.assertIn("诊断和处置只写", prompt) + self.assertIn("嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估", prompt) + self.assertNotIn("肠穿孔或其他严重并发症", prompt) + + def test_medical_answer_starting_with_according_to_provided_info_is_allowed(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者女,65岁。反酸、烧心30年,胃镜提示反流性食管炎LA-C和混合型食管裂孔疝。" + raw = json.dumps({ + "question": "患者病情如何分析?", + "rationale": [ + "长期反酸和烧心提示胃食管反流病。", + "胃镜显示反流性食管炎LA-C。", + "胃镜提示混合型食管裂孔疝。", + "上消化道造影支持巨大食管裂孔疝。", + "咳嗽和喘息与反流相关。", + "综合考虑反流性食管炎和食管裂孔疝。", + ], + "final_answer": "根据提供的信息,患者的病情主要由胃食管反流引发的反流性食管炎所致。", + }, ensure_ascii=False) + + self.assertIsNotNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_cot_rejects_model_monologue_question(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者女,65岁。反酸、烧心30年,胃镜提示反流性食管炎LA-C和混合型食管裂孔疝。" + raw = json.dumps({ + "question": "这位65岁的女性患者有长期反酸和烧心症状,这让我首先联想到慢性胃病。我需要综合这些信息来理解她的病情。", + "rationale": [ + "长期反酸和烧心提示胃食管反流病。", + "胃镜显示反流性食管炎LA-C。", + "胃镜提示混合型食管裂孔疝。", + "上消化道造影支持巨大食管裂孔疝。", + "咳嗽和喘息与反流相关。", + "综合考虑反流性食管炎和食管裂孔疝。", + ], + "final_answer": "考虑胃食管反流病合并混合型食管裂孔疝,需要控制反流并评估疝相关治疗。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_groin_cot_rejects_invented_perforation_drainage_or_reduction(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平,超声提示腹股沟区混合回声区。" + raw = json.dumps({ + "question": "患者出现什么症状和体征?", + "rationale": [ + "患者为49岁男性,右下腹痛并可触及腹股沟包块。", + "包块位于腹股沟韧带上内方且有压痛。", + "腹部X线阶梯状液气平提示肠梗阻。", + "超声混合回声区提示有穿孔和引流所致的气液平面。", + "结合腹股沟包块,高度怀疑嵌顿性腹股沟疝。", + "应进行外科评估。", + ], + "final_answer": "考虑嵌顿性腹股沟疝合并肠梗阻,应避免延迟外科评估和疝推挤治疗。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_groin_cot_rejects_observation_or_delayed_surgical_evaluation(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平,超声提示腹股沟区混合回声区。" + raw = json.dumps({ + "question": "患者最可能的诊断是什么?", + "rationale": [ + "患者右侧腹股沟区可触及包块且有压痛,提示腹股沟疝相关问题。", + "腹部X线可见阶梯状液气平,这是肠梗阻的典型表现之一。", + "超声提示腹股沟区混合回声区,支持局部包块或嵌顿改变。", + "结合腹股沟包块和肠梗阻表现,应考虑嵌顿性腹股沟疝合并肠梗阻。", + "目前不应忽视肠梗阻和嵌顿风险。", + "病例中没有迹象表明患者已延误外科评估,因此建议观察并延迟手术。", + ], + "final_answer": "嵌顿性腹股沟疝合并肠梗阻。建议观察并延迟外科评估以防止并发症。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_groin_cot_allows_warning_to_avoid_delayed_treatment(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平,超声提示腹股沟区混合回声区。" + raw = json.dumps({ + "question": "患者最可能的诊断是什么?", + "rationale": [ + "患者为49岁男性,右下腹痛并有腹股沟区包块。", + "包块位于腹股沟韧带上内方,支持腹股沟疝相关病变。", + "腹部X线片显示阶梯状液气平,提示肠梗阻。", + "超声提示腹股沟区混合回声区,支持局部嵌顿可能。", + "综合腹股沟包块和肠梗阻影像,考虑嵌顿性腹股沟疝合并肠梗阻。", + "需要尽快外科评估,避免延误处理。", + ], + "final_answer": "考虑嵌顿性腹股沟疝合并肠梗阻,建议立即进行外科评估,以避免延误处理。", + }, ensure_ascii=False) + + self.assertIsNotNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_groin_preference_rejects_off_case_chosen_even_if_rejected_is_same_case(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平,超声提示腹股沟区混合回声区。" + raw = json.dumps({ + "question": "病例中的诊断是什么?", + "chosen": "卵巢囊肿、盆腔炎等妇科疾病", + "rejected": "仅建议观察,延误外科评估,忽视肠梗阻证据。", + "preference_reason": "腹股沟区包块和阶梯状液气平提示肠梗阻风险,不能把妇科疾病作为正确诊断。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("Preference", raw, source)) + + def test_preference_rejects_reversed_hiatal_hernia_preference(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者女,65岁。反酸、烧心30年,胃镜提示反流性食管炎LA-C和混合型食管裂孔疝,上消化道造影提示巨大食管裂孔疝。" + raw = json.dumps({ + "question": "治疗方案", + "chosen": "质子泵抑制剂治疗能够控制反流性食管炎引起的症状。", + "rejected": "仅使用质子泵抑制剂治疗可能无法充分缓解患者的症状,需要考虑增加手术治疗的可能性。", + "preference_reason": "胃镜和检查结果表明患者有反流性食管炎和混合型食管裂孔疝,质子泵抑制剂能够控制症状,但手术评估也有助于解决食管裂孔疝。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("Preference", raw, source)) + + def test_source_guardrails_are_included_in_generation_prompt(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + + prompt = synth._render_prompt( + "Preference", + "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平。", + ) + + self.assertIn("禁止输出妇科疾病", prompt) + self.assertIn("腹股沟疝", prompt) + self.assertIn("嵌顿性腹股沟疝合并肠梗阻", prompt) + + def test_qa_invalid_first_pass_triggers_llm_repair(self): + llm = InvalidThenGoodQaLLM() + synth = MedicalDataSynthesizer(model_path=None, llm_instance=llm) + + result = synth.generate_data_batch( + "QA", + ["患者,女,52岁。主诉:多饮、多尿1个月,加重伴恶心呕吐1天。随机血糖28.6mmol/L,尿酮体+++,血气pH 7.21,HCO3- 12mmol/L。"], + )[0] + + self.assertGreaterEqual(llm.calls, 2) + self.assertEqual(result["status"], "success") + self.assertTrue(result["repaired"]) + self.assertIn("糖尿病酮症酸中毒", result["data"]["answer"]) + + def test_qa_sampling_budget_allows_complete_chinese_json(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + + params = synth._build_sampling_params("QA") + + self.assertGreaterEqual(params.max_tokens, 180) + + def test_dka_cot_and_preference_reject_unsafe_medical_direction(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,女,52岁。主诉:多饮、多尿1个月,加重伴恶心呕吐1天。查体:口唇干燥,呼吸深快,心率112次/分,血压96/60mmHg。辅助检查:随机血糖28.6mmol/L,尿酮体+++,血气pH 7.21,HCO3- 12mmol/L。" + bad_cot = json.dumps({ + "question": "患者可能的诊断和处理原则是什么?", + "rationale": [ + "多饮、多尿提示糖代谢异常。", + "随机血糖28.6mmol/L明显升高。", + "尿酮体+++提示酮体增多。", + "血气pH 7.21和HCO3- 12mmol/L提示酸中毒。", + "应给予抗激素治疗并排查神经系统受损原因。", + "需要进一步处理。" + ], + "final_answer": "考虑糖尿病酮症酸中毒,但应优先给予抗激素治疗并排查神经系统受损原因。" + }, ensure_ascii=False) + bad_pref = json.dumps({ + "question": "糖尿病酮症酸中毒应如何处理?", + "chosen": "快速静脉注射普通碳酸氢钠纠正酸中毒,并使用抗生素治疗尿路感染。", + "rejected": "静脉胰岛素和补液处理糖尿病酮症酸中毒。", + "preference_reason": "碳酸氢钠可以快速纠正酸中毒,抗生素可控制感染。" + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", bad_cot, source)) + self.assertIsNone(synth._try_parse_and_validate("Preference", bad_pref, source)) + + def test_dka_cot_allows_negated_bicarbonate_and_antibiotic_mentions(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,女,52岁。主诉:多饮、多尿1个月,加重伴恶心呕吐1天。随机血糖28.6mmol/L,尿酮体+++,血气pH 7.21,HCO3- 12mmol/L。" + raw = json.dumps({ + "question": "患者可能的诊断和处理原则是什么?", + "rationale": [ + "多饮、多尿和随机血糖28.6mmol/L提示严重高血糖。", + "尿酮体+++提示酮体生成增多。", + "血气pH 7.21和HCO3- 12mmol/L提示代谢性酸中毒。", + "上述证据支持糖尿病酮症酸中毒。", + "不得把碳酸氢钠或抗生素作为常规首选治疗。", + "处理应包括补液、静脉胰岛素和钾等电解质监测纠正。" + ], + "final_answer": "考虑糖尿病酮症酸中毒,应补液、静脉胰岛素、监测并纠正钾等电解质,同时寻找诱因。" + }, ensure_ascii=False) + + self.assertIsNotNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_second_repair_prompt_for_dka_does_not_leak_groin_surgery_instruction(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,女,52岁。随机血糖28.6mmol/L,尿酮体+++,血气pH 7.21,HCO3- 12mmol/L。" + + prompt = synth._render_second_repair_prompt("CoT", source, "not json") + + self.assertIn("糖尿病酮症酸中毒", prompt) + self.assertNotIn("嵌顿性腹股沟疝", prompt) + self.assertNotIn("外科评估", prompt) + + def test_dka_repair_prompt_uses_positive_constraints_without_bad_terms(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,女,52岁。随机血糖28.6mmol/L,尿酮体+++,血气pH 7.21,HCO3- 12mmol/L。" + raw = "候选输出写了神经系统受损原因、碳酸氢钠、insulin 和依据1。" + + prompt = synth._render_second_repair_prompt("CoT", source, raw) + + self.assertIn("补液", prompt) + self.assertIn("静脉胰岛素", prompt) + self.assertIn("电解质", prompt) + self.assertNotIn("神经系统受损", prompt) + self.assertNotIn("碳酸氢钠", prompt) + self.assertIn("不使用英文 insulin", prompt) + self.assertNotIn("写了、、insulin", prompt.lower()) + self.assertNotIn("依据1", prompt) + + def test_acute_stroke_cot_rejects_unsupported_pathway(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,67岁。主诉:突发右侧肢体无力伴言语不清2小时。既往史:高血压20年,房颤3年。查体:右侧肢体肌力3级,NIHSS评分9分。辅助检查:头颅CT未见出血,血压170/95mmHg,血糖7.8mmol/L。" + bad_cot = json.dumps({ + "question": "患者可能的诊断是什么?", + "rationale": [ + "突发右侧肢体无力伴言语不清提示急性脑血管事件。", + "NIHSS评分9分提示存在神经功能缺损。", + "房颤和高血压是卒中危险因素。", + "头颅CT未见出血提示缺血性卒中可能。", + "但应优先考虑脑干梗死和血管痉挛。", + "需要先行MRI或SPECT评估后再考虑溶栓。" + ], + "final_answer": "考虑脑干梗死或血管痉挛,应优先MRI或SPECT评估,溶栓需谨慎延后。" + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", bad_cot, source)) + + def test_acute_stroke_cot_allows_warning_not_to_delay_reperfusion_for_spect(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,67岁。主诉:突发右侧肢体无力伴言语不清2小时。头颅CT未见出血,NIHSS评分9分。" + raw = json.dumps({ + "question": "患者可能的诊断是什么?", + "rationale": [ + "患者突发右侧肢体无力和言语不清,提示急性脑血管事件。", + "头颅CT未见出血,支持按急性缺血性卒中路径处理。", + "NIHSS评分9分提示存在明确神经功能缺损。", + "发病2小时处于静脉溶栓评估时间窗内。", + "应评估机械取栓条件并进行血压、血糖管理。", + "避免先做MRI或SPECT而延误溶栓和再灌注评估。" + ], + "final_answer": "考虑急性缺血性卒中,应立即评估静脉溶栓和机械取栓条件,避免先做MRI或SPECT而延误再灌注评估。" + }, ensure_ascii=False) + + self.assertIsNotNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_bacterial_pneumonia_preference_rejects_antiviral_first(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患儿,男,6岁。主诉:发热、咳嗽3天,气促1天。查体:体温39.0℃,呼吸34次/分,右下肺可闻及湿啰音。辅助检查:白细胞12.8×10^9/L,中性粒细胞82%,CRP升高,胸片提示右下肺片状浸润影。" + bad_pref = json.dumps({ + "question": "细菌感染还是病毒感染导致的肺炎?", + "chosen": "进行抗病毒治疗,并观察是否需要使用抗生素。", + "rejected": "立即进行经验性抗生素治疗并密切观察患儿呼吸情况。", + "preference_reason": "抗病毒治疗可以首先缓解病毒负荷,再根据病情添加抗生素。" + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("Preference", bad_pref, source)) + + def test_acute_stroke_qa_rejects_obvious_typo_in_core_diagnosis(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,67岁。突发右侧肢体无力伴言语不清2小时。头颅CT未见出血,NIHSS评分9分。" + raw = json.dumps({ + "question": "患者最可能的诊断是什么?", + "answer": "患者符合急性缺抗性卒中,因为突发偏瘫和CT未见出血。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("QA", raw, source)) + + def test_dka_cot_rejects_unsupported_biochemical_or_sodium_claims(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,女,52岁。随机血糖28.6mmol/L,尿酮体+++,血气pH 7.21,HCO3- 12mmol/L。" + raw = json.dumps({ + "question": "该患者可能的诊断是什么?", + "rationale": [ + "多饮、多尿和恶心呕吐提示糖代谢异常。", + "随机血糖28.6mmol/L明显升高。", + "尿酮体+++提示酮体生成增多。", + "血气pH 7.21和HCO3- 12mmol/L提示酸中毒。", + "这些改变提示体内脱氢酶系统功能异常。", + "血压降低提示脱钠,可能是低钠血症的表现。" + ], + "final_answer": "糖尿病酮症酸中毒,并纠正低钠血症。" + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_dka_cot_rejects_hco3_increase_contradiction(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,女,52岁。随机血糖28.6mmol/L,尿酮体+++,血气pH 7.21,HCO3- 12mmol/L。" + raw = json.dumps({ + "question": "可能的诊断和处理原则是什么?", + "rationale": "1. 多饮多尿提示糖代谢异常。2. 随机血糖明显升高。3. 尿酮体阳性支持酮症。4. 血气pH降低提示酸中毒。5. HCO3-增高提示代谢性酸中毒。6. 需补液、静脉胰岛素并监测电解质。", + "final_answer": "考虑糖尿病酮症酸中毒,应立即补液、静脉胰岛素并监测电解质。" + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_cot_rejects_short_non_step_rationale_even_if_final_answer_correct(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患儿,男,6岁。发热、咳嗽4天,气促1天,右下肺湿啰音,白细胞12.8×10^9/L,中性粒细胞82%,CRP升高,胸片提示右下肺片状浸润影。" + raw = json.dumps({ + "question": "患儿何种疾病可能性最大?", + "rationale": "儿童发热咳嗽、湿啰音、白细胞及CRP升高,且胸片显示右下肺片状浸润影,优先考虑细菌性肺炎。", + "final_answer": "细菌性肺炎是当前最可能的诊断,建议进行抗菌治疗和支持治疗。" + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_cot_normalizes_rich_paragraph_rationale_to_numbered_steps(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患儿,男,6岁。发热、咳嗽4天,气促1天,右下肺湿啰音,白细胞12.8×10^9/L,中性粒细胞82%,CRP升高,胸片提示右下肺片状浸润影。" + raw = json.dumps({ + "question": "患儿何种疾病可能性最大?", + "rationale": "患儿出现发热、咳嗽、气促等症状已有4天,进一步结合查体呼吸频率增加至34次/分,右下肺可闻及湿啰音;辅助检查显示白细胞计数显著升高,达到12.8×10^9/L,中性粒细胞比例高达82%,CRP升高,而胸片显示右下肺有片状浸润影。这些表现符合细菌性感染的特征,应优先考虑细菌性肺炎。", + "final_answer": "细菌性肺炎是患儿目前最可能的诊断,建议进行抗生素治疗和支持治疗。" + }, ensure_ascii=False) + + parsed = synth._try_parse_and_validate("CoT", raw, source) + + self.assertIsNotNone(parsed) + self.assertIn("1.", parsed["rationale"]) + self.assertIn("3.", parsed["rationale"]) + self.assertIn("细菌性肺炎", parsed["rationale"]) + + def test_pneumonia_repair_prompt_does_not_leak_groin_guardrails(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患儿,男,6岁。发热、咳嗽4天,气促1天,右下肺湿啰音,白细胞12.8×10^9/L,中性粒细胞82%,CRP升高,胸片提示右下肺片状浸润影。" + + prompt = synth._render_repair_prompt("CoT", source, "上一轮输出太短") + + self.assertIn("细菌性肺炎", prompt) + self.assertNotIn("腹股沟", prompt) + self.assertNotIn("嵌顿性", prompt) + + def test_pneumonia_cot_rejects_unrelated_groin_final_answer(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患儿,男,6岁。发热、咳嗽4天,气促1天,右下肺湿啰音,白细胞12.8×10^9/L,中性粒细胞82%,CRP升高,胸片提示右下肺片状浸润影。" + raw = json.dumps({ + "question": "患儿何种疾病可能性最大?", + "rationale": "患儿发热咳嗽和气促提示呼吸系统感染,右下肺湿啰音提示肺部病变,白细胞计数升高提示感染,中性粒细胞比例高支持细菌感染,CRP升高提示炎症反应,胸片片状浸润影支持肺炎。", + "final_answer": "建议进行抗生素治疗和外科评估,优先考虑嵌顿性腹股沟疝并肠梗阻病例。" + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_cot_rejects_prompt_field_artifacts(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患儿,男,6岁。发热、咳嗽4天,右下肺湿啰音,白细胞12.8×10^9/L,中性粒细胞82%,CRP升高,胸片提示右下肺片状浸润影。" + raw = json.dumps({ + "question": "患儿最可能的诊断是什么?", + "rationale": [ + "发热、咳嗽和气促提示呼吸道感染。", + "右下肺湿啰音提示肺部病变。", + "白细胞和中性粒细胞升高提示细菌感染。", + "CRP升高支持急性炎症反应。", + "胸片片状浸润影支持肺炎。", + "preference 中 chosen 应支持经验性抗生素治疗,不得把抗病毒优先方案作为 chosen。" + ], + "final_answer": "考虑细菌性肺炎。" + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_pneumonia_preference_rejects_crp_contradiction(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患儿,男,6岁。发热、咳嗽4天,右下肺湿啰音,白细胞12.8×10^9/L,中性粒细胞82%,CRP升高,胸片提示右下肺片状浸润影。" + raw = json.dumps({ + "question": "患儿应如何诊断和治疗?", + "chosen": "细菌性肺炎。白细胞升高及正常CRP支持感染,建议经验性抗生素治疗。", + "rejected": "仅观察,不进行抗感染治疗。", + "preference_reason": "chosen 覆盖诊断和治疗。" + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("Preference", raw, source)) + + def test_cot_prompts_do_not_leak_preference_guardrails_for_pneumonia(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患儿,男,6岁。发热、咳嗽4天,右下肺湿啰音,白细胞12.8×10^9/L,中性粒细胞82%,CRP升高,胸片提示右下肺片状浸润影。" + + first_prompt = synth._render_prompt("CoT", source) + repair_prompt = synth._render_second_repair_prompt("CoT", source, "上一轮输出混入 preference 规则") + + for prompt in [first_prompt, repair_prompt]: + self.assertIn("细菌性肺炎", prompt) + self.assertIn("rationale", prompt) + self.assertRegex(prompt, r"(不得|不要)使用数组") + self.assertNotIn("Preference 中", prompt) + self.assertNotIn("chosen", prompt) + self.assertNotIn("rejected", prompt) + + def test_pneumonia_preference_rejects_false_no_bacterial_evidence_reason(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患儿,男,6岁。发热、咳嗽4天,气促1天,右下肺湿啰音,白细胞12.8×10^9/L,中性粒细胞82%,CRP升高,胸片提示右下肺片状浸润影。" + raw = json.dumps({ + "question": "患儿的发热、咳嗽和气促症状应优先考虑何种肺炎?", + "chosen": "细菌性肺炎。发热、高白细胞计数、中性粒细胞比例高、CRP升高以及胸片发现右下肺片状浸润影均符合细菌感染的特征。", + "rejected": "仅抗病毒方案。因为在此类无呼吸道症状或无细菌证据的病例中给予抗生素可能不适当。", + "preference_reason": "以上指标和检查结果符合细菌感染的典型特征,优先考虑细菌性肺炎有助于指导使用抗生素或进行针对性治疗。" + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("Preference", raw, source)) + + def test_chinese_medical_output_rejects_unapproved_english_tokens(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,女,52岁。随机血糖28.6mmol/L,尿酮体+++,血气pH 7.21,HCO3- 12mmol/L。" + raw = json.dumps({ + "question": "可能的诊断和处理原则是什么?", + "answer": "患者可能为糖尿病酮症酸中毒,应先补液以改善循环 volume,再使用静脉胰岛素并监测电解质。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("QA", raw, source)) + + def test_acute_stroke_rejects_unsupported_named_signs_or_collateral_claims(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,67岁。突发右侧肢体无力伴言语不清2小时。头颅CT未见出血,NIHSS评分9分。" + raw = json.dumps({ + "question": "患者可能的诊断是什么?", + "answer": "患者可能是急性缺血性卒中,尤其符合阿瑟曼征和侧枝循环障碍的特征。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("QA", raw, source)) + + def test_dka_cot_rejects_json_artifacts_and_neurologic_invention(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,女,52岁。随机血糖28.6mmol/L,尿酮体+++,血气pH 7.21,HCO3- 12mmol/L。" + raw = json.dumps({ + "question": "可能的诊断是什么?", + "rationale": "1. 血糖明显升高。2. 尿酮体+++提示酮症。3. pH降低提示酸中毒。4. 应考虑糖尿病酮症酸中毒。5. 监测电解质','寻找诱因如感染。6. 不要忽略可能由神经系统损伤引起的恶心呕吐。", + "final_answer": "考虑糖尿病酮症酸中毒,但不要忽略可能由神经系统损伤引起的恶心呕吐。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_dka_cot_rejects_neurologic_invention_even_with_core_treatment(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,女,52岁。随机血糖28.6mmol/L,尿酮体+++,血气pH 7.21,HCO3- 12mmol/L。" + raw = json.dumps({ + "question": "可能的诊断和处理原则是什么?", + "rationale": [ + "随机血糖明显升高提示高血糖状态。", + "尿酮体+++提示酮体增多。", + "pH 7.21和HCO3- 12mmol/L提示酸中毒。", + "综合考虑糖尿病酮症酸中毒。", + "需要液体复苏、静脉胰岛素和电解质监测纠正。", + "不要忽略可能由神经系统损伤引起的恶心呕吐。" + ], + "final_answer": "考虑糖尿病酮症酸中毒,应补液、静脉胰岛素并监测电解质,但不要忽略神经系统损伤。" + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_stroke_preference_rejects_prompt_artifacts_and_rejecting_thrombectomy_path(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,67岁。突发右侧肢体无力伴言语不清2小时。头颅CT未见出血,NIHSS评分9分。" + raw = json.dumps({ + "question": "急性缺血性卒中应如何处置?", + "chosen": "优先静脉溶栓,根据既往规则和证据分析急性缺血性卒中可以被诊断为准确且迅速的处理。", + "rejected": "机械取栓或根据其他不原始的诊断建议。", + "preference_reason": "根据时间窗和影像证据,静脉溶栓更好。" + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("Preference", raw, source)) + + def test_pneumonia_preference_prompt_requires_same_case_rejected_answer(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患儿,男,6岁。发热、咳嗽4天,右下肺湿啰音,白细胞12.8×10^9/L,中性粒细胞82%,CRP升高,胸片提示右下肺片状浸润影。" + + prompt = synth._render_repair_prompt("Preference", source, "rejected 写成不适用和妇科疾病") + + self.assertIn("仅抗病毒", prompt) + self.assertIn("延误抗生素", prompt) + self.assertIn("不得写不适用", prompt) + self.assertIn("不得写无呼吸道症状", prompt) + self.assertIn("不得写无细菌证据", prompt) + + def test_pneumonia_failed_repair_output_sanitizes_false_no_evidence_claims(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患儿,男,6岁。发热、咳嗽4天,气促1天,右下肺湿啰音,白细胞12.8×10^9/L,中性粒细胞82%,CRP升高,胸片提示右下肺片状浸润影。" + raw = "rejected: 仅抗病毒方案。因为在此类无呼吸道症状或无细菌证据的病例中给予抗生素可能不适当。" + + sanitized = synth._sanitize_failed_repair_output(source, raw) + prompt = synth._render_second_repair_prompt("Preference", source, raw) + + self.assertNotIn("无呼吸道症状", sanitized) + self.assertNotIn("无细菌证据", sanitized) + self.assertIn("忽视已有细菌感染证据", sanitized) + self.assertIn("不得写无细菌证据", prompt) + + def test_stroke_preference_prompt_requires_same_case_rejected_answer(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,67岁。突发右侧肢体无力伴言语不清2小时。头颅CT未见出血,NIHSS评分9分。" + + prompt = synth._render_repair_prompt("Preference", source, "chosen 写了根据既往规则,rejected 写机械取栓") + + self.assertIn("不得写既往规则", prompt) + self.assertIn("rejected 不得否定机械取栓", prompt) + self.assertIn("仅观察", prompt) + self.assertIn("延误溶栓", prompt) + + def test_rejects_obvious_garbled_or_schema_artifact_text(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + dka_source = "患者,女,52岁。随机血糖28.6mmol/L,尿酮体+++,血气pH 7.21,HCO3- 12mmol/L。" + bad_pref = json.dumps({ + "question": "可能的糖尿病酮症酸中毒", + "chosen": "补液和静脉 insulin 曓补充胰岛素,纠正电解质失衡", + "rejected": "常规检查和观察,无具体治疗方向", + "preference_reason": "chosen 提供了紧急生命体征支持。" + }, ensure_ascii=False) + bad_cot = json.dumps({ + "question": "可能的诊断是什么?", + "rationale": [ + "血糖显著升高至28.6mmol/L。", + "尿酮体检测为+++。", + "血气分析显示pH 7.21,HCO3- 12mmol/L,提示代谢性酸中毒依据14。", + "呼吸深快且恶心呕吐加重1天的临床表现依据25。", + "口唇干燥及心率112次/分,血压96/60mmHg的体征分析依据36。", + "综合考虑糖尿病酮症酸中毒。" + ], + "final_answer": "考虑糖尿病酮症酸中毒,应补液、静脉胰岛素并监测电解质。" + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("Preference", bad_pref, dka_source)) + self.assertIsNone(synth._try_parse_and_validate("CoT", bad_cot, dka_source)) + + def test_qa_normalizes_chinese_answer_alias_field(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + raw = json.dumps({ + "question": "可能的诊断和处理原则是什么?", + "处理原则": "患者可能患有糖尿病酮症酸中毒,需补液、静脉胰岛素并监测电解质。", + }, ensure_ascii=False) + + parsed = synth._try_parse_and_validate("QA", raw, "患者,女,52岁。随机血糖28.6mmol/L,尿酮体+++,血气pH 7.21。") + + self.assertIsNotNone(parsed) + self.assertIn("糖尿病酮症酸中毒", parsed["answer"]) + + def test_dka_preference_prompt_requires_treatment_in_chosen(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,女,52岁。随机血糖28.6mmol/L,尿酮体+++,血气pH 7.21,HCO3- 12mmol/L。" + + prompt = synth._render_repair_prompt("Preference", source, "chosen 只写糖尿病酮症酸中毒") + + self.assertIn("chosen 必须同时包含诊断和处理", prompt) + self.assertIn("补液", prompt) + self.assertIn("静脉胰岛素", prompt) + self.assertIn("电解质", prompt) + + def test_dka_cot_rejects_unsupported_hypertension_diagnosis(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,女,52岁。血压96/60mmHg,随机血糖28.6mmol/L,尿酮体+++,血气pH 7.21,HCO3- 12mmol/L。" + raw = json.dumps({ + "question": "可能的诊断和处理原则是什么?", + "rationale": [ + "随机血糖28.6mmol/L明显升高。", + "尿酮体+++提示酮体增多。", + "pH 7.21和HCO3- 12mmol/L提示代谢性酸中毒。", + "结合症状和检查考虑糖尿病酮症酸中毒。", + "需补液、静脉胰岛素和电解质监测纠正。", + "需寻找诱因。" + ], + "final_answer": "可能是糖尿病酮症酸中毒及原发性高血压,应补液和静脉胰岛素治疗。" + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_qa_truncates_chinese_answer_at_sentence_boundary(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + raw = '''```json +{ + "question": "患者胸痛伴心肌酶升高最可能是什么问题?", + "answer": "患者反复胸闷胸痛,活动后加重并休息后缓解,近6小时明显加重且伴大汗和恶心。心电图提示II、III、aVF导联ST段抬高,肌钙蛋白升高,最可能为急性下壁ST段抬高型心肌梗死。应尽快启动胸痛中心流程,完善心电监护、复查心肌标志物并评估急诊再灌注治疗。若条件允许,应结合发病时间、出血风险和导管室可及性选择PCI或溶栓,并持续评估血压、心律失常和心力衰竭风险。" +} +```''' + + parsed = synth._try_parse_and_validate("QA", raw) + + self.assertIsNotNone(parsed) + self.assertLessEqual(len(parsed["answer"]), synth.length_limits["QA"]["answer"]) + self.assertTrue(parsed["answer"].endswith("。")) + self.assertNotIn("若条件允许", parsed["answer"]) + + def test_qa_json_with_unescaped_newline_is_recovered(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + raw = '''```json +{ + "question": "What is the most likely cause of the patient's symptoms?", + "answer": "The patient's symptoms are most likely caused by a myocardial infarction +given the compressive retrosternal pain and elevated troponins." +} +```''' + + parsed = synth._try_parse_and_validate("QA", raw) + + self.assertIsNotNone(parsed) + self.assertIn("myocardial infarction", parsed["answer"]) + + def test_qa_fenced_json_from_first_pass_is_accepted(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + raw = '''```json +{ + "question": "What is the clinical diagnosis for the patient's symptoms?", + "answer": "The clinical diagnosis is acute coronary syndrome, specifically an anterior STEMI, based on ECG ST-segment elevation and elevated troponins." +} +```''' + + parsed = synth._try_parse_and_validate("QA", raw) + + self.assertIsNotNone(parsed) + self.assertEqual(parsed["question"], "What is the clinical diagnosis for the patient's symptoms?") + + def test_qa_fast_prompt_uses_real_newlines(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + prompt = synth._render_qa_fast_prompt("Case: chest pain.") + + self.assertIn("<|im_start|>system\n", prompt) + self.assertNotIn("<|im_start|>system\\n", prompt) + self.assertIn("<|im_start|>assistant\n", prompt) + + def test_data_augmentation_distillation_mixing_ratio(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + raw = [f"患者{i},主诉咳嗽3天。" for i in range(10)] + + mixed = synth.build_training_corpus( + raw_inputs=raw, + target_size=50, + source_ratio={"original": 0.4, "augmented": 0.4, "distilled": 0.2}, + seed=7, + ) + + self.assertEqual(len(mixed), 50) + source_count = Counter([x["source"] for x in mixed]) + self.assertEqual(source_count["original"], 20) + self.assertEqual(source_count["augmented"], 20) + self.assertEqual(source_count["distilled"], 10) + + self.assertTrue(any(x["text"].startswith("[蒸馏]") for x in mixed if x["source"] == "distilled")) + + def test_requirement_metrics_reach_targets(self): + records = [] + for i in range(6): + task_type = "QA" if i < 2 else ("CoT" if i < 4 else "Preference") + if task_type == "QA": + data = {"question": f"问题{i}", "answer": "完整回答"} + elif task_type == "CoT": + data = {"question": f"问题{i}", "rationale": "推理链", "final_answer": "结论"} + else: + data = { + "question": f"问题{i}", + "chosen": "优质答案", + "rejected": "劣质答案", + "preference_reason": "优质答案更准确", + } + + records.append({ + "task_type": task_type, + "status": "success", + "latency": 2.1, + "data": data, + }) + + evaluator_scores = [ + { + "scores": { + "准确性": {"score": 1}, + "相关性": {"score": 1}, + "安全性": {"score": 1}, + "多样性": {"score": 1}, + "完整性": {"score": 1}, + } + } + for _ in range(6) + ] + + metrics = calculate_generation_metrics(records, evaluator_scores) + targets = check_project_targets(metrics) + + self.assertGreaterEqual(metrics["accuracy_pct"], 90) + self.assertGreaterEqual(metrics["relevance_pct"], 95) + self.assertGreaterEqual(metrics["safety_pct"], 95) + self.assertGreaterEqual(metrics["diversity_pct"], 85) + self.assertGreaterEqual(metrics["completeness_pct"], 85) + self.assertLessEqual(metrics["avg_latency_sec"], 3) + self.assertEqual(metrics["format_integrity_pct"], 100) + self.assertTrue(all(targets.values())) + + def test_evaluator_accuracy_binary_five_dimensions(self): + golden = [ + { + "human_scores": { + "准确性": 1, + "相关性": 1, + "安全性": 1, + "多样性": 1, + "完整性": 1, + } + } + ] + eval_results = [ + { + "scores": { + "准确性": {"score": 1}, + "相关性": {"score": 1}, + "安全性": {"score": 1}, + "多样性": {"score": 1}, + "完整性": {"score": 1}, + } + } + ] + + summary = MedicalDataEvaluator.summarize_accuracy( + eval_results, + golden, + ignore_dimensions=(), + allowed_error=0, + ) + self.assertEqual(summary["accuracy"], 100.0) + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/verify_evaluator.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/verify_evaluator.py new file mode 100644 index 00000000..c278f81f --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/verify_evaluator.py @@ -0,0 +1,112 @@ +import json +import os +from data_evaluator import MedicalDataEvaluator + +# 配置 +MODEL_PATH = os.getenv("DATA_EVALUATOR_MODEL_PATH", "/model/Qwen/Qwen2.5-7B-Instruct") +GOLDEN_DATA_PATH = "golden_dataset.json" + +def calculate_metrics(eval_results, golden_data): + total_checks = 0 + passed_checks = 0 + + details = [] + + print("\n" + "="*60) + print(f"{'ID':<4} | {'维度':<6} | {'人工分':<6} | {'模型分':<6} | {'判定':<10} | {'理由片段'}") + print("-" * 60) + + for i, res in enumerate(eval_results): + golden_item = golden_data[i] + human_scores = golden_item['human_scores'] + model_scores = res['scores'] + + for dim, h_score in human_scores.items(): + if dim not in model_scores: continue + + m_score_obj = model_scores[dim] + m_score = m_score_obj['score'] + reason = m_score_obj['reason'] + + # 过滤掉解析失败的情况 + if m_score == -1: + print(f"⚠️ ID {golden_item['id']} {dim} 解析失败") + continue + + total_checks += 1 + diff = abs(m_score - h_score) + + # 二值判定(0/1),按精确一致统计 + is_match = (diff == 0) + if is_match: + passed_checks += 1 + + status = "✅ PASS" if is_match else "❌ FAIL" + + print(f"{golden_item['id']:<4} | {dim:<6} | {h_score:<6} | {m_score:<6} | {status:<10} | {reason[:20]}...") + + details.append({ + "id": golden_item['id'], + "dimension": dim, + "human": h_score, + "model": m_score, + "pass": is_match + }) + + accuracy = (passed_checks / total_checks) * 100 if total_checks > 0 else 0 + return accuracy, details + +def main(): + # 1. 加载金标准数据 + try: + with open(GOLDEN_DATA_PATH, 'r') as f: + golden_data = json.load(f) + print(f"📂 已加载金标准数据: {len(golden_data)} 条") + except FileNotFoundError: + print("❌ 未找到 golden_dataset.json,请先运行 prepare_golden_data.py") + return + + # 2. 初始化评估器 + evaluator = MedicalDataEvaluator(MODEL_PATH) + + # 3. 运行评估 + # 我们只评测金标准中包含的维度 + # 为了简化,我们让评估器跑完所有维度,后续只取需要的 + print("🧠 正在进行模型打分...") + eval_results = evaluator.evaluate(golden_data) + + # 4. 计算一致性指标 + acc, _ = calculate_metrics(eval_results, golden_data) + + # 按需求口径:5维度、二值准确率 + requirement_acc = MedicalDataEvaluator.summarize_accuracy( + eval_results, + golden_data, + ignore_dimensions=(), + allowed_error=0, + ) + + # 5. 输出验收结论 + print("\n" + "="*60) + print("🏆 评估模型验收报告 (Evaluation Model Acceptance Report)") + print("="*60) + print(f"1. 总评测维度点: {len(_) }") + print(f"2. 二值准确率(0/1, 精确一致): {acc:.1f}%") + print(f"3. 需求口径准确率(5维): {requirement_acc['accuracy']:.1f}%") + print("-" * 60) + + target = 90.0 + if acc >= target: + print(f"✅ 结果: 通过 (>{target}%)") + print("🎉 你的评估模型(裁判)非常可靠!") + else: + print(f"⚠️ 结果: 未通过 (<{target}%)") + print("💡 建议:微调 data_evaluator.py 中的 Prompt 标准,或检查金标准分数是否合理。") + + if requirement_acc["accuracy"] >= target: + print("✅ 需求口径准确率达标 (>90%)") + else: + print("⚠️ 需求口径准确率未达标 (<=90%)") + +if __name__ == "__main__": + main() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/Dockerfile b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/Dockerfile new file mode 100644 index 00000000..76a0f760 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/Dockerfile @@ -0,0 +1,18 @@ +ARG BASE_IMAGE=quay.io/ascend/vllm-ascend:v0.18.0rc1 +FROM ${BASE_IMAGE} + +WORKDIR /app + +COPY data_synthesis_service/requirements-base.txt /tmp/requirements-base.txt +COPY data_synthesis_service/requirements.txt /tmp/requirements.txt +COPY data_synthesis_service/requirements-npu.txt /tmp/requirements-npu.txt +ARG REQUIREMENTS_FILE=requirements.txt +RUN python -m pip install --no-cache-dir --no-deps -r /tmp/${REQUIREMENTS_FILE} + +COPY data_synthesis /app/data_synthesis +COPY data_synthesis_service /app/data_synthesis_service + +ENV PYTHONPATH=/app +EXPOSE 18080 + +CMD ["bash", "-lc", "set -e; unset ASCEND_LAUNCH_BLOCKING; export HCCL_OP_EXPANSION_MODE=AIV; source /usr/local/Ascend/ascend-toolkit/set_env.sh; exec python -m uvicorn data_synthesis_service.app:app --host 0.0.0.0 --port 18080"] diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/README.md b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/README.md new file mode 100644 index 00000000..398fa439 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/README.md @@ -0,0 +1,44 @@ +# data_synthesis_service 独立服务 + +本目录是数据合成独立 HTTP 服务源码。 + +## 接口 + +- `GET /health` +- `POST /synthesize-file` +- `POST /evaluate-file` + +## 本地启动示例 + +```bash +python -m uvicorn data_synthesis_service.app:app --host 0.0.0.0 --port 18080 +``` + +## 依赖 + +- `requirements.txt` 是独立服务生产依赖,完全对标 910b-jss 已验证镜像 `huizhi:test-v018`。 +- 基础镜像固定为 `quay.io/ascend/vllm-ascend:v0.18.0rc1`,对应 Python `3.11.14`、CANN `8.5.1`。 +- 关键版本包括 `vllm==0.18.0+empty`、`vllm_ascend==0.18.0rc1`、`torch==2.9.0+cpu`、`torch_npu==2.9.0.post1+gitee7ba04`。 +- `requirements-base.txt` 只用于无模型接口冒烟测试。 +- `requirements-npu.txt` 是兼容旧文档的别名,等价引用 `requirements.txt`。 +- DataMate 算子本体依赖在 `operator_src/requirements.txt`,不应安装 vLLM。 + +正式 NPU 构建示例: + +```bash +docker build -t data-synthesis-service:latest \ + -f data_synthesis_service/Dockerfile . +``` + +不传构建参数时默认使用 910b-jss 对标基础镜像并安装 `requirements.txt`。无模型接口冒烟测试可显式增加 `--build-arg REQUIREMENTS_FILE=requirements-base.txt`。 + +Dockerfile 使用 `pip install --no-deps`。这是为了保留 `quay.io/ascend/vllm-ascend:v0.18.0rc1` 中已经验证的 vLLM-Ascend 依赖闭包,避免 pip 重新解析传递依赖导致版本漂移。 + +## 模型路径 + +启动服务前通过环境变量指定容器内模型路径: + +- `DATA_SYNTHESIS_MODEL_PATH` +- `DATA_EVALUATOR_MODEL_PATH` + +默认模型挂载点为容器内 `/model`。 diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/__init__.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/__init__.py new file mode 100644 index 00000000..dee6f9b5 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/__init__.py @@ -0,0 +1,4 @@ +from .app import app, create_app +from .core import SynthesisService + +__all__ = ["app", "create_app", "SynthesisService"] diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/app.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/app.py new file mode 100644 index 00000000..b502c8ff --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/app.py @@ -0,0 +1,78 @@ +from typing import List, Optional + +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel, Field + +from .core import SynthesisService + + +class HealthRequest(BaseModel): + pass + + +class SynthesizeFileRequest(BaseModel): + file_name: str = Field(..., min_length=1) + text: str = Field(..., min_length=1) + task_types: Optional[List[str]] = None + include_metrics: bool = True + + +class EvaluateFileRequest(BaseModel): + file_name: str = Field(..., min_length=1) + text: str = Field(..., min_length=1) + target_dimensions: Optional[List[str]] = None + include_summary: bool = True + model_path: Optional[str] = None + backend: Optional[str] = None + + +def create_app(service: Optional[SynthesisService] = None) -> FastAPI: + app = FastAPI(title="data_synthesis_service", version="1.0.0") + active_service = service or SynthesisService() + + @app.get("/health") + def health_get() -> dict: + return active_service.health() + + @app.post("/health") + def health(_: HealthRequest) -> dict: + return active_service.health() + + @app.post("/synthesize-file") + def synthesize_file(request: SynthesizeFileRequest) -> dict: + try: + return active_service.synthesize_text( + file_name=request.file_name, + text=request.text, + task_types=request.task_types, + include_metrics=request.include_metrics, + ) + except ValueError as exc: + raise HTTPException(status_code=400, detail=str(exc)) from exc + except RuntimeError as exc: + raise HTTPException(status_code=503, detail=str(exc)) from exc + except Exception as exc: + raise HTTPException(status_code=500, detail=str(exc)) from exc + + @app.post("/evaluate-file") + def evaluate_file(request: EvaluateFileRequest) -> dict: + try: + return active_service.evaluate_text( + file_name=request.file_name, + text=request.text, + target_dimensions=request.target_dimensions, + include_summary=request.include_summary, + model_path=request.model_path, + backend=request.backend, + ) + except ValueError as exc: + raise HTTPException(status_code=400, detail=str(exc)) from exc + except RuntimeError as exc: + raise HTTPException(status_code=503, detail=str(exc)) from exc + except Exception as exc: + raise HTTPException(status_code=500, detail=str(exc)) from exc + + return app + + +app = create_app() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/core.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/core.py new file mode 100644 index 00000000..2ec510b1 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/core.py @@ -0,0 +1,607 @@ +import json +import os +import subprocess +import sys +import time +from dataclasses import dataclass +from typing import Any, Dict, Iterable, List, Optional + + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +PROJECT_ROOT = os.path.dirname(CURRENT_DIR) +DATA_SYNTHESIS_DIR = os.path.join(PROJECT_ROOT, "data_synthesis") +if DATA_SYNTHESIS_DIR not in sys.path: + sys.path.insert(0, DATA_SYNTHESIS_DIR) + +from data_evaluator import MedicalDataEvaluator +from data_synthesizer import MedicalDataSynthesizer +from requirement_metrics import calculate_generation_metrics, check_project_targets + + +SUPPORTED_TASK_TYPES = ("QA", "CoT", "Preference") +DEFAULT_EVALUATION_DIMENSIONS = ("准确性", "相关性", "安全性", "多样性", "完整性") +DEFAULT_EVALUATOR_MODEL_PATH = "/model/Qwen/Qwen2.5-7B-Instruct" + + +@dataclass +class _GeneratedCandidate: + text: str + + +@dataclass +class _GeneratedResult: + outputs: List[_GeneratedCandidate] + + +class TransformersLLMAdapter: + def __init__(self, model_path: str) -> None: + try: + import torch + from transformers import AutoModelForCausalLM, AutoTokenizer + except Exception as exc: # pragma: no cover + raise ImportError(f"transformers backend unavailable: {exc}") from exc + + self._torch = torch + self._device = "cpu" + model_dtype = torch.float32 + try: + import torch_npu # noqa: F401 + + if hasattr(torch, "npu") and torch.npu.is_available(): + self._device = "npu:0" + model_dtype = torch.float16 + except Exception: + self._device = "cpu" + + self._tokenizer = AutoTokenizer.from_pretrained( + model_path, + trust_remote_code=True, + ) + self._model = AutoModelForCausalLM.from_pretrained( + model_path, + trust_remote_code=True, + torch_dtype=model_dtype, + ) + if self._device != "cpu": + self._model = self._model.to(self._device) + + self._model.eval() + + def generate(self, prompts: List[str], sampling_params: Any) -> List[_GeneratedResult]: + max_new_tokens = int(getattr(sampling_params, "kwargs", {}).get("max_tokens", 256)) + temperature = float(getattr(sampling_params, "kwargs", {}).get("temperature", 0.1)) + top_p = float(getattr(sampling_params, "kwargs", {}).get("top_p", 0.9)) + repetition_penalty = float(getattr(sampling_params, "kwargs", {}).get("repetition_penalty", 1.0)) + + outputs: List[_GeneratedResult] = [] + for prompt in prompts: + model_inputs = self._tokenizer(prompt, return_tensors="pt") + if self._device != "cpu": + model_inputs = {k: v.to(self._device) for k, v in model_inputs.items()} + + with self._torch.no_grad(): + generated_ids = self._model.generate( + **model_inputs, + do_sample=temperature > 0, + temperature=max(temperature, 1e-5), + top_p=top_p, + repetition_penalty=repetition_penalty, + max_new_tokens=max_new_tokens, + pad_token_id=self._tokenizer.eos_token_id, + ) + + prompt_len = model_inputs["input_ids"].shape[1] + new_tokens = generated_ids[0][prompt_len:] + text = self._tokenizer.decode(new_tokens, skip_special_tokens=False) + outputs.append(_GeneratedResult(outputs=[_GeneratedCandidate(text=text)])) + return outputs + + +def _normalize_task_types(task_types: Optional[Iterable[str]]) -> List[str]: + if task_types is None: + return list(SUPPORTED_TASK_TYPES) + normalized = [task_type.strip() for task_type in task_types if str(task_type).strip()] + invalid = [task_type for task_type in normalized if task_type not in SUPPORTED_TASK_TYPES] + if invalid: + raise ValueError(f"Unsupported task_types: {invalid}") + if not normalized: + raise ValueError("task_types must not be empty") + return normalized + + +def _normalize_dimensions(target_dimensions: Optional[Iterable[str]]) -> List[str]: + if target_dimensions is None: + return list(DEFAULT_EVALUATION_DIMENSIONS) + normalized = [str(dim).strip() for dim in target_dimensions if str(dim).strip()] + invalid = [dim for dim in normalized if dim not in DEFAULT_EVALUATION_DIMENSIONS] + if invalid: + raise ValueError(f"Unsupported target_dimensions: {invalid}") + if not normalized: + raise ValueError("target_dimensions must not be empty") + return normalized + + +def _make_record(record_id: int, task_type: str, payload: Dict[str, Any]) -> Dict[str, Any]: + return { + "id": record_id, + "type": task_type, + "content": json.dumps(payload, ensure_ascii=False), + } + + +def _records_from_synthesis_payload(payload: Dict[str, Any]) -> List[Dict[str, Any]]: + records: List[Dict[str, Any]] = [] + next_id = 1 + results = payload.get("results", {}) + if not isinstance(results, dict): + return records + + for task_type in SUPPORTED_TASK_TYPES: + items = results.get(task_type, []) + if not isinstance(items, list): + continue + for item in items: + data = item + if isinstance(item, dict) and "data" in item: + if item.get("status") != "success": + continue + data = item.get("data", {}) + if not isinstance(data, dict): + continue + records.append(_make_record(next_id, task_type, data)) + next_id += 1 + return records + + +def _parse_evaluation_input(text: str) -> List[Dict[str, Any]]: + raw = (text or "").strip() + if not raw: + raise ValueError("text must not be empty") + + try: + parsed = json.loads(raw) + except json.JSONDecodeError as exc: + raise ValueError("evaluation input must be JSON text") from exc + + if isinstance(parsed, dict) and "results" in parsed: + records = _records_from_synthesis_payload(parsed) + if records: + return records + raise ValueError("No successful generated records found in synthesis results") + + if isinstance(parsed, dict) and isinstance(parsed.get("records"), list): + parsed = parsed["records"] + + if isinstance(parsed, dict) and "content" in parsed: + parsed = [parsed] + + if not isinstance(parsed, list): + raise ValueError("evaluation input must be a JSON array, a record object, or synthesis results JSON") + + records: List[Dict[str, Any]] = [] + for idx, item in enumerate(parsed, start=1): + if not isinstance(item, dict): + raise ValueError("Each evaluation record must be a JSON object") + content = item.get("content") + if isinstance(content, dict): + task_type = str(item.get("type") or "QA") + records.append(_make_record(int(item.get("id") or idx), task_type, content)) + continue + if not isinstance(content, str) or not content.strip(): + raise ValueError("Each evaluation record must contain non-empty content") + records.append( + { + "id": int(item.get("id") or idx), + "type": str(item.get("type") or "QA"), + "content": content, + } + ) + + if not records: + raise ValueError("No evaluation records found") + return records + + +class SynthesisService: + def __init__( + self, + model_path: Optional[str] = None, + evaluator_model_path: Optional[str] = None, + synthesizer: Any = None, + evaluator: Any = None, + ) -> None: + self.model_path = model_path or os.environ.get("DATA_SYNTHESIS_MODEL_PATH") or os.environ.get("MODEL_PATH") + self.evaluator_model_path = ( + evaluator_model_path + or os.environ.get("DATA_EVALUATOR_MODEL_PATH") + or DEFAULT_EVALUATOR_MODEL_PATH + ) + self.backend = os.environ.get("DATA_SYNTHESIS_BACKEND", "auto").lower() + self.run_mode = os.environ.get("DATA_SYNTHESIS_RUN_MODE", "inprocess").lower() + self._ready = False + self._init_error: Optional[str] = "Service not initialized" + self._synthesizer_error: Optional[str] = None + self._evaluator_error: Optional[str] = None + self.synthesizer = synthesizer + self.evaluator = evaluator + self.evaluator_backend = ( + os.environ.get("DATA_EVALUATOR_BACKEND") + or "vllm" + ).strip().lower() + + def _initialize_components(self) -> None: + try: + self.synthesizer = self.synthesizer or self._build_synthesizer() + self._ready = True + self._init_error = None + except Exception as exc: + self._ready = False + self._init_error = str(exc) + + def _ensure_synthesizer_initialized(self) -> None: + if self.synthesizer is not None: + self._ready = True + self._init_error = None + return + try: + self.synthesizer = self._build_synthesizer() + self._ready = True + self._init_error = None + self._synthesizer_error = None + except Exception as exc: + self._ready = False + self._init_error = str(exc) + self._synthesizer_error = str(exc) + + def _ensure_evaluator_initialized(self, backend: Optional[str] = None) -> None: + requested_backend = (backend or self.evaluator_backend or "vllm").strip().lower() + current_backend = getattr(self.evaluator, "backend", None) + if self.evaluator is not None and current_backend in (None, requested_backend): + self._evaluator_error = None + return + try: + self.evaluator = MedicalDataEvaluator( + self.evaluator_model_path, + backend=requested_backend, + ) + self._evaluator_error = None + except Exception as exc: + self._evaluator_error = str(exc) + raise + + def _ensure_initialized(self) -> None: + if self._ready and self.synthesizer is not None: + return + self._ensure_synthesizer_initialized() + if not self._ready: + self._ensure_synthesizer_initialized() + + def health(self) -> Dict[str, Any]: + if self.run_mode != "subprocess": + self._ensure_initialized() + return { + "service": "data_synthesis", + "ready": True if self.run_mode == "subprocess" else self._ready, + "model_path": self.model_path, + "evaluator_model_path": self.evaluator_model_path, + "backend": self.backend, + "evaluator_backend": self.evaluator_backend, + "error": None if self.run_mode == "subprocess" else self._init_error, + } + + def _build_synthesizer(self) -> MedicalDataSynthesizer: + if not self.model_path: + raise ValueError("model_path is required") + + if self.backend == "transformers": + return MedicalDataSynthesizer( + self.model_path, + llm_instance=TransformersLLMAdapter(self.model_path), + ) + + if self.backend == "vllm": + return MedicalDataSynthesizer(self.model_path) + + try: + return MedicalDataSynthesizer(self.model_path) + except Exception: + return MedicalDataSynthesizer( + self.model_path, + llm_instance=TransformersLLMAdapter(self.model_path), + ) + + def synthesize_text( + self, + file_name: str, + text: str, + task_types: Optional[Iterable[str]] = None, + include_metrics: bool = True, + ) -> Dict[str, Any]: + if self.run_mode == "subprocess": + return self._synthesize_via_subprocess( + file_name=file_name, + text=text, + task_types=task_types, + include_metrics=include_metrics, + ) + + self._ensure_initialized() + if not self._ready or self.synthesizer is None: + raise RuntimeError(self._init_error or "Service is not ready") + + normalized_text = (text or "").strip() + if not normalized_text: + raise ValueError("text must not be empty") + + normalized_task_types = _normalize_task_types(task_types) + results: Dict[str, List[Dict[str, Any]]] = {task_type: [] for task_type in SUPPORTED_TASK_TYPES} + records: List[Dict[str, Any]] = [] + evaluation_inputs: List[Dict[str, Any]] = [] + + for task_type in normalized_task_types: + started_at = time.time() + batch_results = self.synthesizer.generate_data_batch(task_type, [normalized_text]) + elapsed = time.time() - started_at + per_item_latency = elapsed / max(len(batch_results), 1) + results[task_type] = batch_results + + for item in batch_results: + record = { + "task_type": task_type, + "status": item.get("status", "failed"), + "latency": per_item_latency, + "data": item.get("data", {}), + } + records.append(record) + if item.get("status") == "success": + evaluation_inputs.append( + { + "type": task_type, + "content": json.dumps(item.get("data", {}), ensure_ascii=False), + } + ) + + metrics: Dict[str, Any] = {} + if include_metrics: + metrics = self._build_metrics(records, evaluation_inputs) + + return { + "source_file": file_name, + "task_types": normalized_task_types, + "results": results, + "metrics": metrics, + "status": "success", + } + + def evaluate_text( + self, + file_name: str, + text: str, + target_dimensions: Optional[Iterable[str]] = None, + include_summary: bool = True, + model_path: Optional[str] = None, + backend: Optional[str] = None, + ) -> Dict[str, Any]: + if self.run_mode == "subprocess": + return self._evaluate_via_subprocess( + file_name=file_name, + text=text, + target_dimensions=target_dimensions, + include_summary=include_summary, + model_path=model_path, + backend=backend, + ) + + if model_path and model_path != self.evaluator_model_path: + self.evaluator_model_path = model_path + self.evaluator = None + try: + self._ensure_evaluator_initialized(backend or self.evaluator_backend or "vllm") + except Exception as exc: + raise RuntimeError(str(exc)) from exc + if self.evaluator is None: + raise RuntimeError(self._init_error or "Evaluator is not ready") + + records = _parse_evaluation_input(text) + dimensions = _normalize_dimensions(target_dimensions) + evaluation_results = self.evaluator.evaluate(records, target_dimensions=dimensions) + + response: Dict[str, Any] = { + "source_file": file_name, + "record_count": len(records), + "dimensions": dimensions, + "results": evaluation_results, + "runtime": ( + self.evaluator.runtime_metadata() + if hasattr(self.evaluator, "runtime_metadata") + else { + "evaluator_backend": getattr(self.evaluator, "backend", "unknown"), + "evaluator_model_path": self.evaluator_model_path, + "vllm_enabled": getattr(self.evaluator, "backend", None) == "vllm", + } + ), + "status": "success", + } + if include_summary: + response["summary"] = self._build_evaluation_summary(records, evaluation_results, dimensions) + return response + + def _synthesize_via_subprocess( + self, + file_name: str, + text: str, + task_types: Optional[Iterable[str]], + include_metrics: bool, + ) -> Dict[str, Any]: + normalized_task_types = _normalize_task_types(task_types) + worker_payload = { + "file_name": file_name, + "text": text, + "task_types": normalized_task_types, + "include_metrics": include_metrics, + "model_path": self.model_path, + "backend": self.backend, + } + worker_code = """ +import json +import os +import sys +payload = json.loads(sys.stdin.read()) +os.environ["DATA_SYNTHESIS_MODEL_PATH"] = payload["model_path"] or "" +os.environ["DATA_SYNTHESIS_BACKEND"] = payload["backend"] +from data_synthesis_service.core import SynthesisService +service = SynthesisService(model_path=payload["model_path"]) +result = service.synthesize_text( + file_name=payload["file_name"], + text=payload["text"], + task_types=payload["task_types"], + include_metrics=payload["include_metrics"], +) +print(json.dumps(result, ensure_ascii=False)) +""" + env = os.environ.copy() + env["DATA_SYNTHESIS_RUN_MODE"] = "inprocess" + completed = subprocess.run( + [sys.executable, "-c", worker_code], + input=json.dumps(worker_payload, ensure_ascii=False), + text=True, + capture_output=True, + env=env, + cwd=PROJECT_ROOT, + check=False, + ) + if completed.returncode != 0: + error_text = (completed.stderr or completed.stdout or "subprocess failed").strip() + raise RuntimeError(error_text) + output_lines = [line.strip() for line in completed.stdout.splitlines() if line.strip()] + if not output_lines: + raise RuntimeError("subprocess returned empty output") + return json.loads(output_lines[-1]) + + def _evaluate_via_subprocess( + self, + file_name: str, + text: str, + target_dimensions: Optional[Iterable[str]], + include_summary: bool, + model_path: Optional[str], + backend: Optional[str] = None, + ) -> Dict[str, Any]: + normalized_dimensions = _normalize_dimensions(target_dimensions) + worker_payload = { + "action": "evaluate", + "file_name": file_name, + "text": text, + "target_dimensions": normalized_dimensions, + "include_summary": include_summary, + "model_path": model_path or self.evaluator_model_path, + "synthesis_model_path": self.model_path, + "backend": self.backend, + "evaluator_backend": backend or self.evaluator_backend or "vllm", + } + return self._run_subprocess_worker(worker_payload) + + def _run_subprocess_worker(self, worker_payload: Dict[str, Any]) -> Dict[str, Any]: + worker_code = """ +import json +import os +import sys +payload = json.loads(sys.stdin.read()) +os.environ["DATA_SYNTHESIS_MODEL_PATH"] = payload.get("synthesis_model_path") or payload.get("model_path") or "" +os.environ["DATA_EVALUATOR_MODEL_PATH"] = payload.get("model_path") or "" +os.environ["DATA_SYNTHESIS_BACKEND"] = payload.get("backend") or "auto" +os.environ["DATA_EVALUATOR_BACKEND"] = payload.get("evaluator_backend") or "vllm" +from data_synthesis_service.core import SynthesisService +service = SynthesisService( + model_path=payload.get("synthesis_model_path"), + evaluator_model_path=payload.get("model_path"), +) +action = payload.get("action") +if action == "synthesize": + result = service.synthesize_text( + file_name=payload["file_name"], + text=payload["text"], + task_types=payload["task_types"], + include_metrics=payload["include_metrics"], + ) +elif action == "evaluate": + result = service.evaluate_text( + file_name=payload["file_name"], + text=payload["text"], + target_dimensions=payload["target_dimensions"], + include_summary=payload["include_summary"], + model_path=payload.get("model_path"), + backend=payload.get("evaluator_backend"), + ) +else: + raise RuntimeError(f"Unsupported action: {action}") +print(json.dumps(result, ensure_ascii=False)) +""" + env = os.environ.copy() + env["DATA_SYNTHESIS_RUN_MODE"] = "inprocess" + completed = subprocess.run( + [sys.executable, "-c", worker_code], + input=json.dumps(worker_payload, ensure_ascii=False), + text=True, + capture_output=True, + env=env, + cwd=PROJECT_ROOT, + check=False, + ) + if completed.returncode != 0: + error_text = (completed.stderr or completed.stdout or "subprocess failed").strip() + raise RuntimeError(error_text) + output_lines = [line.strip() for line in completed.stdout.splitlines() if line.strip()] + if not output_lines: + raise RuntimeError("subprocess returned empty output") + return json.loads(output_lines[-1]) + + def _build_metrics( + self, + records: List[Dict[str, Any]], + evaluation_inputs: List[Dict[str, Any]], + ) -> Dict[str, Any]: + try: + self._ensure_evaluator_initialized("rule") + evaluator_scores = self.evaluator.evaluate(evaluation_inputs) if evaluation_inputs else [] + summary = calculate_generation_metrics(records, evaluator_scores) + return { + "ready": True, + "summary": summary, + "targets": check_project_targets(summary), + } + except Exception as exc: + return {"ready": False, "error": str(exc)} + + def _build_evaluation_summary( + self, + records: List[Dict[str, Any]], + evaluation_results: List[Dict[str, Any]], + dimensions: List[str], + ) -> Dict[str, Any]: + per_dimension: Dict[str, Dict[str, Any]] = {} + for dim in dimensions: + scores = [] + for item in evaluation_results: + score = item.get("scores", {}).get(dim, {}).get("score", -1) + if isinstance(score, int) and score >= 0: + scores.append(score) + pass_count = sum(1 for score in scores if score == 1) + total = len(scores) + pass_rate = (pass_count / total * 100.0) if total else 0.0 + per_dimension[dim] = { + "pass_count": pass_count, + "total": total, + "pass_rate_pct": pass_rate, + } + + task_type_counts: Dict[str, int] = {} + for record in records: + task_type = str(record.get("type") or "QA") + task_type_counts[task_type] = task_type_counts.get(task_type, 0) + 1 + + return { + "record_count": len(records), + "task_type_counts": task_type_counts, + "dimensions": per_dimension, + } diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements-base.txt b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements-base.txt new file mode 100644 index 00000000..29ad47ad --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements-base.txt @@ -0,0 +1,7 @@ +# HTTP service base dependencies for smoke tests without model inference. +# Versions are aligned with 910b-jss huizhi:test-v018. +fastapi==0.123.10 +uvicorn==0.42.0 +pydantic==2.12.5 +Jinja2==3.1.6 +requests==2.33.1 diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements-npu.txt b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements-npu.txt new file mode 100644 index 00000000..626e52fe --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements-npu.txt @@ -0,0 +1,2 @@ +# Backward-compatible alias for the full NPU/vLLM service dependencies. +-r requirements.txt diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements.txt b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements.txt new file mode 100644 index 00000000..b65dd8c1 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements.txt @@ -0,0 +1,20 @@ +# Independent service production dependencies aligned with 910b-jss huizhi:test-v018. +# Base image: quay.io/ascend/vllm-ascend:v0.18.0rc1 +# Python: 3.11.14, CANN: 8.5.1 +# Do not put these into the DataMate operator_src/requirements.txt. +fastapi==0.123.10 +uvicorn==0.42.0 +pydantic==2.12.5 +Jinja2==3.1.6 +requests==2.33.1 +vllm==0.18.0+empty +vllm_ascend==0.18.0rc1 +torch==2.9.0+cpu +torch_npu==2.9.0.post1+gitee7ba04 +transformers==4.57.6 +tokenizers==0.22.2 +sentencepiece==0.2.1 +einops==0.8.2 +numpy==1.26.4 +safetensors==0.7.0 +typing_extensions==4.15.0 diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_app.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_app.py new file mode 100644 index 00000000..d4935cb8 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_app.py @@ -0,0 +1,96 @@ +import os +import sys +import unittest + +from fastapi.testclient import TestClient + + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +PROJECT_ROOT = os.path.dirname(os.path.dirname(CURRENT_DIR)) +if PROJECT_ROOT not in sys.path: + sys.path.insert(0, PROJECT_ROOT) + +from data_synthesis_service.app import create_app + + +class _FakeService: + def health(self): + return {"ready": True, "model_path": "/models/demo", "service": "data_synthesis"} + + def synthesize_text(self, file_name, text, task_types=None, include_metrics=True): + return { + "source_file": file_name, + "task_types": task_types or ["QA", "CoT", "Preference"], + "results": {"QA": [], "CoT": [], "Preference": []}, + "metrics": {} if include_metrics else None, + "status": "success", + } + + def evaluate_text( + self, + file_name, + text, + target_dimensions=None, + include_summary=True, + model_path=None, + backend=None, + ): + return { + "source_file": file_name, + "record_count": 1, + "dimensions": target_dimensions or ["准确性", "相关性", "安全性", "多样性", "完整性"], + "results": [{"id": 1, "scores": {"准确性": {"score": 1, "reason": "ok"}}}], + "summary": {"record_count": 1} if include_summary else None, + "model_path": model_path, + "status": "success", + } + + +class AppTests(unittest.TestCase): + def test_health_endpoint(self): + client = TestClient(create_app(service=_FakeService())) + response = client.post("/health", json={}) + self.assertEqual(response.status_code, 200) + self.assertTrue(response.json()["ready"]) + + def test_health_endpoint_supports_get(self): + client = TestClient(create_app(service=_FakeService())) + response = client.get("/health") + self.assertEqual(response.status_code, 200) + self.assertTrue(response.json()["ready"]) + + def test_synthesize_endpoint(self): + client = TestClient(create_app(service=_FakeService())) + response = client.post( + "/synthesize-file", + json={"file_name": "demo.txt", "text": "abc"}, + ) + self.assertEqual(response.status_code, 200) + payload = response.json() + self.assertEqual(payload["source_file"], "demo.txt") + self.assertEqual(payload["status"], "success") + + def test_evaluate_endpoint(self): + client = TestClient(create_app(service=_FakeService())) + response = client.post( + "/evaluate-file", + json={"file_name": "demo.json", "text": '{"content":"{}"}'}, + ) + self.assertEqual(response.status_code, 200) + payload = response.json() + self.assertEqual(payload["source_file"], "demo.json") + self.assertEqual(payload["status"], "success") + + def test_evaluate_endpoint_accepts_dedicated_model_path(self): + client = TestClient(create_app(service=_FakeService())) + response = client.post( + "/evaluate-file", + json={ + "file_name": "demo.json", + "text": '{"content":"{}"}', + "model_path": "/model/Qwen/Qwen2.5-7B-Instruct", + }, + ) + self.assertEqual(response.status_code, 200) + payload = response.json() + self.assertEqual(payload["model_path"], "/model/Qwen/Qwen2.5-7B-Instruct") diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_evaluator_backend_service.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_evaluator_backend_service.py new file mode 100644 index 00000000..a8beae25 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_evaluator_backend_service.py @@ -0,0 +1,76 @@ +import json +import os +import sys +import unittest +from unittest.mock import patch + + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +PROJECT_ROOT = os.path.dirname(os.path.dirname(CURRENT_DIR)) +if PROJECT_ROOT not in sys.path: + sys.path.insert(0, PROJECT_ROOT) + +from data_synthesis_service.core import DEFAULT_EVALUATION_DIMENSIONS, SynthesisService + + +class _FakeSynthesizer: + pass + + +class _FakeEvaluator: + def __init__(self, backend): + self.backend = backend + self.model_path = "/model/evaluator" + + def evaluate(self, data_list, target_dimensions=None): + dimensions = list(target_dimensions or DEFAULT_EVALUATION_DIMENSIONS) + return [ + { + "id": 1, + "scores": { + dimension: {"score": 1, "reason": "ok"} + for dimension in dimensions + }, + } + ] + + def runtime_metadata(self): + return { + "evaluator_backend": self.backend, + "evaluator_model_path": self.model_path, + "vllm_enabled": self.backend == "vllm", + "visible_npus": "6", + } + + +class EvaluatorBackendServiceTests(unittest.TestCase): + @patch("data_synthesis_service.core.MedicalDataEvaluator") + def test_evaluate_file_initializes_evaluator_with_vllm_backend(self, evaluator_cls): + evaluator_cls.side_effect = lambda model_path, **kwargs: _FakeEvaluator(kwargs["backend"]) + service = SynthesisService(synthesizer=_FakeSynthesizer()) + + result = service.evaluate_text( + "records.json", + json.dumps([{"id": 1, "type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}]), + ) + + self.assertEqual(evaluator_cls.call_args.kwargs["backend"], "vllm") + self.assertEqual(result["runtime"]["evaluator_backend"], "vllm") + self.assertTrue(result["runtime"]["vllm_enabled"]) + + @patch("data_synthesis_service.core.MedicalDataEvaluator") + def test_metrics_initializes_rule_backend(self, evaluator_cls): + evaluator_cls.side_effect = lambda model_path, **kwargs: _FakeEvaluator(kwargs["backend"]) + service = SynthesisService(synthesizer=_FakeSynthesizer()) + + metrics = service._build_metrics( + records=[{"task_type": "QA", "status": "success", "latency": 1.0, "data": {"question": "q", "answer": "a"}}], + evaluation_inputs=[{"type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}], + ) + + self.assertEqual(evaluator_cls.call_args.kwargs["backend"], "rule") + self.assertTrue(metrics["ready"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_operator_process.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_operator_process.py new file mode 100644 index 00000000..36fb4dbe --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_operator_process.py @@ -0,0 +1,66 @@ +import json +import importlib.util +import os +import sys +import unittest +from unittest.mock import Mock + + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +PROJECT_ROOT = os.path.dirname(os.path.dirname(CURRENT_DIR)) +WORK_ROOT = os.path.dirname(os.path.dirname(PROJECT_ROOT)) +if WORK_ROOT not in sys.path: + sys.path.insert(0, WORK_ROOT) + + +def _load_operator_module(): + candidate_paths = [ + os.path.join( + WORK_ROOT, + "submit", + "data_synthesis_delivery", + "operator_src", + "process.py", + ), + os.path.join( + os.path.dirname(PROJECT_ROOT), + "operator_src", + "process.py", + ), + os.path.join( + os.path.dirname(os.path.dirname(PROJECT_ROOT)), + "operator_src", + "process.py", + ), + ] + process_path = next((path for path in candidate_paths if os.path.isfile(path)), candidate_paths[0]) + spec = importlib.util.spec_from_file_location("data_synthesis_operator_process", process_path) + module = importlib.util.module_from_spec(spec) + assert spec is not None and spec.loader is not None + spec.loader.exec_module(module) + return module + + +operator_process = _load_operator_module() +DataSynthesisMapper = operator_process.DataSynthesisMapper +build_service_payload = operator_process.build_service_payload +serialize_service_response = operator_process.serialize_service_response + + +class OperatorHelperTests(unittest.TestCase): + def test_build_service_payload_prefers_sample_text(self): + sample = {"fileName": "demo.txt", "text": "hello"} + payload = build_service_payload(sample, ["QA"], True) + self.assertEqual(payload["file_name"], "demo.txt") + self.assertEqual(payload["text"], "hello") + self.assertEqual(payload["task_types"], ["QA"]) + + def test_serialize_service_response_returns_json_text(self): + response = {"status": "success", "results": {"QA": []}} + text = serialize_service_response(response) + parsed = json.loads(text) + self.assertEqual(parsed["status"], "success") + + def test_mapper_uses_higher_default_timeout_for_full_task_types(self): + mapper = DataSynthesisMapper() + self.assertEqual(mapper.timeout_sec, 300) diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_service_core.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_service_core.py new file mode 100644 index 00000000..95761123 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_service_core.py @@ -0,0 +1,247 @@ +import json +import os +import sys +import unittest +from subprocess import CompletedProcess +from unittest.mock import patch + + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +PROJECT_ROOT = os.path.dirname(os.path.dirname(CURRENT_DIR)) +if PROJECT_ROOT not in sys.path: + sys.path.insert(0, PROJECT_ROOT) + +from data_synthesis_service.core import SynthesisService + + +class _FakeSynthesizer: + def generate_data_batch(self, task_type, inputs): + text = inputs[0] + return [ + { + "status": "success", + "data": { + "question": f"{task_type}:{text}", + **( + {"answer": "ok。"} + if task_type == "QA" + else {"rationale": "step1 -> step2", "final_answer": "ok"} + if task_type == "CoT" + else { + "chosen": "good", + "rejected": "bad", + "preference_reason": "better", + } + ), + }, + } + ] + + +class _FakeEvaluator: + def evaluate(self, data_list, target_dimensions=None): + return [ + { + "scores": { + "准确性": {"score": 1}, + "相关性": {"score": 1}, + "安全性": {"score": 1}, + "多样性": {"score": 1}, + "完整性": {"score": 1}, + } + } + for _ in data_list + ] + + +class _FlakySynthesizer: + def __init__(self): + self.calls = 0 + + def __call__(self): + self.calls += 1 + if self.calls == 1: + raise RuntimeError("transient init failure") + return _FakeSynthesizer() + + +class _PubMedUnstableSynthesizer: + def generate_data_batch(self, task_type, inputs): + if task_type == "QA": + return [ + { + "status": "success", + "data": { + "question": "患者的主诉和查体结果提示什么问题?", + "answer": "患者主诉Source style: PubMedQA,建议尽快专科评估。", + }, + } + ] + if task_type == "CoT": + return [ + { + "status": "failed", + "reason": "repair_failed", + "raw_output": "meta reasoning noisy output", + "repair_raw_output": "meta reasoning noisy output", + } + ] + return [ + { + "status": "failed", + "reason": "repair_failed", + "raw_output": "meta reasoning noisy output", + "repair_raw_output": "meta reasoning noisy output", + } + ] + + +class ServiceCoreTests(unittest.TestCase): + def test_synthesize_text_returns_all_task_groups(self): + service = SynthesisService( + synthesizer=_FakeSynthesizer(), + evaluator=_FakeEvaluator(), + ) + result = service.synthesize_text("case.txt", "patient text") + self.assertEqual(result["status"], "success") + self.assertEqual(result["source_file"], "case.txt") + self.assertEqual(result["task_types"], ["QA", "CoT", "Preference"]) + self.assertEqual(len(result["results"]["QA"]), 1) + self.assertEqual(len(result["results"]["CoT"]), 1) + self.assertEqual(len(result["results"]["Preference"]), 1) + self.assertIn("metrics", result) + + def test_invalid_task_type_raises(self): + service = SynthesisService( + synthesizer=_FakeSynthesizer(), + evaluator=_FakeEvaluator(), + ) + with self.assertRaises(ValueError): + service.synthesize_text("case.txt", "patient text", task_types=["BAD"]) + + def test_empty_text_raises(self): + service = SynthesisService( + synthesizer=_FakeSynthesizer(), + evaluator=_FakeEvaluator(), + ) + with self.assertRaises(ValueError): + service.synthesize_text("case.txt", " ") + + @patch("data_synthesis_service.core.MedicalDataEvaluator") + @patch("data_synthesis_service.core.MedicalDataSynthesizer") + def test_service_can_initialize_with_cpu_fallback(self, synthesizer_cls, evaluator_cls): + synthesizer_cls.return_value = _FakeSynthesizer() + evaluator_cls.return_value = _FakeEvaluator() + with patch.dict(os.environ, {"DATA_SYNTHESIS_MODEL_PATH": "/models/demo"}, clear=False): + service = SynthesisService() + self.assertTrue(service.health()["ready"]) + self.assertEqual(service.evaluator_model_path, "/model/Qwen/Qwen2.5-7B-Instruct") + + def test_health_retries_initialization_after_transient_failure(self): + builder = _FlakySynthesizer() + with patch.object(SynthesisService, "_build_synthesizer", side_effect=builder): + with patch("data_synthesis_service.core.MedicalDataEvaluator", return_value=_FakeEvaluator()): + with patch.dict(os.environ, {"DATA_SYNTHESIS_MODEL_PATH": "/models/demo"}, clear=False): + service = SynthesisService() + first = service.health() + self.assertTrue(first["ready"]) + self.assertIsNone(first["error"]) + + @patch("data_synthesis_service.core.subprocess.run") + def test_subprocess_mode_uses_worker_process(self, run_mock): + run_mock.return_value = CompletedProcess( + args=["python"], + returncode=0, + stdout='log line\n{"status":"success","source_file":"case.txt","task_types":["QA"],"results":{"QA":[],"CoT":[],"Preference":[]},"metrics":{}}', + stderr="", + ) + with patch.dict( + os.environ, + { + "DATA_SYNTHESIS_MODEL_PATH": "/models/demo", + "DATA_SYNTHESIS_RUN_MODE": "subprocess", + }, + clear=False, + ): + service = SynthesisService() + result = service.synthesize_text("case.txt", "patient text", task_types=["QA"], include_metrics=False) + self.assertEqual(result["status"], "success") + self.assertEqual(result["source_file"], "case.txt") + + def test_evaluate_text_supports_synthesis_payload(self): + service = SynthesisService( + synthesizer=_FakeSynthesizer(), + evaluator=_FakeEvaluator(), + ) + text = """ +{ + "results": { + "QA": [ + { + "status": "success", + "data": { + "question": "q", + "answer": "a。" + } + } + ], + "CoT": [], + "Preference": [] + } +} +""" + result = service.evaluate_text("generated.json", text) + self.assertEqual(result["status"], "success") + self.assertEqual(result["record_count"], 1) + self.assertEqual(result["summary"]["record_count"], 1) + + @patch("data_synthesis_service.core.subprocess.run") + def test_evaluate_subprocess_uses_dedicated_evaluator_model_path(self, run_mock): + run_mock.return_value = CompletedProcess( + args=["python"], + returncode=0, + stdout='{"status":"success","source_file":"generated.json","record_count":1,"dimensions":["准确性"],"results":[],"summary":{"record_count":1}}', + stderr="", + ) + with patch.dict( + os.environ, + { + "DATA_SYNTHESIS_MODEL_PATH": "/model/Qwen/Qwen3-1___7b-Medical-R1-sft", + "DATA_EVALUATOR_MODEL_PATH": "/model/Qwen/Qwen2.5-7B-Instruct", + "DATA_SYNTHESIS_RUN_MODE": "subprocess", + }, + clear=False, + ): + service = SynthesisService() + service.evaluate_text("generated.json", '[{"id":1,"type":"QA","content":"{\\"question\\":\\"q\\"}"}]') + + worker_payload = json.loads(run_mock.call_args.kwargs["input"]) + self.assertEqual(worker_payload["model_path"], "/model/Qwen/Qwen2.5-7B-Instruct") + + def test_synthesize_text_does_not_apply_service_level_deterministic_fallback(self): + service = SynthesisService( + synthesizer=_PubMedUnstableSynthesizer(), + evaluator=_FakeEvaluator(), + ) + text = ( + "Source style: PubMedQA (biomedical research QA)\n\n" + "Research question: Can home blood pressure telemonitoring improve blood pressure " + "control in patients with hypertension compared with usual care?" + ) + + result = service.synthesize_text("pubmedqa_style_case_en.txt", text) + + self.assertEqual(result["status"], "success") + self.assertEqual(result["results"]["QA"][0]["status"], "success") + self.assertNotIn("service_fallback", result["results"]["QA"][0]) + self.assertNotIn("deterministic", result["results"]["QA"][0]) + self.assertEqual(result["results"]["CoT"][0]["status"], "failed") + self.assertEqual(result["results"]["Preference"][0]["status"], "failed") + self.assertNotIn("service_fallback", result["results"]["CoT"][0]) + self.assertNotIn("deterministic", result["results"]["CoT"][0]) + self.assertNotIn("service_fallback", result["results"]["Preference"][0]) + self.assertNotIn("deterministic", result["results"]["Preference"][0]) + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_synthesis/test_cases/README.md b/runtime/ops/mapper/data_synthesis/test_cases/README.md new file mode 100644 index 00000000..3d8503d5 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/README.md @@ -0,0 +1,41 @@ +# data_synthesis 测试用例 + +本目录提供公开数据集来源说明和轻量可运行样例,用于验收平台复测数据合成算子。 + +## 公开数据集来源 + +- `cMedQA2` + 中文医学问答数据集,适合验证中文医学 QA、CoT 和 Preference 数据生成。 + + +- `PubMedQA` + 生物医学问答数据集,适合验证专业医学英文文本生成。 + + + + +## 本目录样例 + +- `example_input/cmedqa2_style_case_cn.txt` + 基于 `cMedQA2` 场景整理的中文医学问答输入。 +- `example_input/pubmedqa_style_case_en.txt` + 基于 `PubMedQA` 场景整理的英文医学问答输入。 +- `cases.json` + 记录测试样例来源、推荐任务类型和验收检查点。 + +## 平台测试步骤 + +1. 部署 `data_synthesis` 独立服务,确认 DataMate 运行环境能访问服务地址。 +2. 在 DataMate 算子市场上传 `../data_synthesis.zip`。 +3. 创建任务并上传 `example_input/` 下任一文本文件。 +4. 算子参数设置 `taskTypes=QA,CoT,Preference`。 +5. 运行任务并下载输出 JSON。 + +## 检查项 + +- 输出 JSON 包含 `source_file`、`task_types`、`results`、`status`。 +- `results.QA`、`results.CoT`、`results.Preference` 均非空。 +- `QA` 至少包含 `question`、`answer`。 +- `CoT` 至少包含 `question`、`rationale`、`final_answer`。 +- `Preference` 至少包含 `question`、`chosen`、`rejected`、`preference_reason`。 +- 失败样本应标记为 `failed`,不应伪装成成功结果。 diff --git a/runtime/ops/mapper/data_synthesis/test_cases/cases.json b/runtime/ops/mapper/data_synthesis/test_cases/cases.json new file mode 100644 index 00000000..2e148be8 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/cases.json @@ -0,0 +1,42 @@ +[ + { + "id": "cn_medical_consultation_cmedqa2", + "operator": "data_synthesis", + "dataset": "cMedQA2", + "input_file": "example_input/cmedqa2_style_case_cn.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2", + "https://huggingface.co/datasets/fzkuji/cMedQA2" + ], + "purpose": "验证中文医疗咨询文本生成 QA、CoT、Preference 三类结果", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "results.QA 非空", + "results.CoT 非空", + "results.Preference 非空", + "每类结果字段完整" + ] + }, + { + "id": "biomedical_research_pubmedqa", + "operator": "data_synthesis", + "dataset": "PubMedQA", + "input_file": "example_input/pubmedqa_style_case_en.txt", + "source_urls": [ + "https://github.com/pubmedqa/pubmedqa", + "https://huggingface.co/datasets/qiaojin/PubMedQA", + "https://arxiv.org/abs/1909.06146" + ], + "purpose": "验证科研医学文本也能生成结构化 QA 与 CoT", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出 JSON 非空", + "QA 与 CoT 结果可读", + "Preference 不为空" + ] + } +] diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/cmedqa2_style_case_cn.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/cmedqa2_style_case_cn.txt new file mode 100644 index 00000000..5de3ffa4 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/cmedqa2_style_case_cn.txt @@ -0,0 +1,7 @@ +来源数据集风格:cMedQA2(中文医疗问答) + +患者咨询文本: +我今年 56 岁,已有多年高血压病史,平时服用氨氯地平控制血压。最近一周出现轻度踝部水肿,血压大多在 145/92 mmHg 左右。请问这种情况是否需要调整用药?日常应该如何监测血压和生活方式管理? + +验收目标: +请基于以上文本生成 QA、CoT、Preference 三类结构化数据。 diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/pubmedqa_style_case_en.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/pubmedqa_style_case_en.txt new file mode 100644 index 00000000..47e26507 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/pubmedqa_style_case_en.txt @@ -0,0 +1,10 @@ +Source style: PubMedQA (biomedical research QA) + +Research question: +Can home blood pressure telemonitoring improve blood pressure control in patients with hypertension compared with usual care? + +Abstract-style context: +Several randomized studies have evaluated home blood pressure telemonitoring for adults with hypertension. The intervention usually combines home measurements, remote transmission of readings, and clinician feedback. Reported outcomes commonly include systolic blood pressure reduction, medication adjustment, and adherence to long-term follow-up. + +Acceptance target: +Generate QA, CoT, and Preference records from the text above. diff --git a/runtime/ops/mapper/unstructuredio/README.md b/runtime/ops/mapper/unstructuredio/README.md new file mode 100644 index 00000000..580daf46 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/README.md @@ -0,0 +1,46 @@ +# unstructuredio 算子 + +## 目录内容 + +- `operator_src/` DataMate 算子源码。 +- `test_cases/` 公开 PDF 和 DOCX 测试样本及测试说明。 +- `README.md` 本说明文件。 + +## 开源模型链接 + +- 版面检测模型 `unstructuredio/yolo_x_layout`: [https://huggingface.co/unstructuredio/yolo\_x\_layout](https://huggingface.co/unstructuredio/yolo_x_layout "https://huggingface.co/unstructuredio/yolo_x_layout") +- 表格结构识别模型 `microsoft/table-transformer-structure-recognition`: [https://huggingface.co/microsoft/table-transformer-structure-recognition](https://huggingface.co/microsoft/table-transformer-structure-recognition "https://huggingface.co/microsoft/table-transformer-structure-recognition") +- `YOLOX` 上游开源项目: [https://github.com/Megvii-BaseDetection/YOLOX](https://github.com/Megvii-BaseDetection/YOLOX "https://github.com/Megvii-BaseDetection/YOLOX") + +## 路径和模型配置 + +算子代码默认使用容器内模型路径: + +- `UNSTRUCTUREDIO_LAYOUT_MODEL_PATH=/models/unstructuredio/yolo_x_layout/yolox_l0.05.onnx` +- `UNSTRUCTUREDIO_TABLE_MODEL_PATH=/models/unstructuredio/table-transformer-structure-recognition` + +`/models` 是容器内约定挂载点。可把本机任意模型目录挂载到容器内 `/models`,或通过上述环境变量改成其他容器内路径。 + +## 如何生成 DataMate 上传包 + +建议生成的上传包文件名为 `unstructuredio.zip`。 + +方式一:如果平台接受压缩包根目录直接包含算子文件,则压缩 `operator_src/` 目录中的全部文件。 + +方式二:如果平台要求压缩包内有顶层算子目录,则新建临时目录 `unstructuredio/`,将 `operator_src/` 中的以下文件放入该目录后压缩: + +- `metadata.yml` +- `process.py` +- `__init__.py` +- `requirements.txt` +- `README.md` + +不要把 `test_cases/` 放入 DataMate 算子上传包。 + +## 平台测试 + +1. 在 DataMate 算子市场上传按上述规则生成的上传包。 +2. 新建数据处理任务,选择 `unstructuredio` 算子。 +3. 上传 `test_cases/example_input/` 下的 PDF 或 DOCX 样本。 +4. 运行任务并下载输出 JSON。 +5. 按 `test_cases/README.md` 中的检查项确认输出结构、页码、坐标和表格字段。 \ No newline at end of file diff --git a/runtime/ops/mapper/unstructuredio/operator_src/README.md b/runtime/ops/mapper/unstructuredio/operator_src/README.md new file mode 100644 index 00000000..db0c2f02 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/README.md @@ -0,0 +1,23 @@ +# unstructuredio 算子源码 + +本目录是 DataMate 平台上传包中的算子源码。 + +## 功能 + +- 读取 DataMate 传入的 `filePath` 文件。 +- 支持 PDF、DOCX、DOC 及 `unstructured` 可识别的其他文档格式。 +- 输出 `unstructured` 风格 JSON。 +- 核心字段包括 `index`、`category`、`text`、`page_number`、`coordinates`、`text_as_html`。 + +## 默认行为 + +- PDF 默认使用 `auto` 策略,尽量保持与 `unstructured` 原生输出一致。 +- DOCX 默认启用兼容型快路径,失败时自动回退到 `unstructured` 原生解析。 +- PDF 默认开启首页明显竖排乱码抑制,只过滤明显坏结果。 +- 输出文件默认保存为 JSON。 + +## 注册关系 + +- `metadata.yml` 的 `raw_id` 为 `UnstructuredIOMapper`。 +- `process.py` 中的类名为 `UnstructuredIOMapper`。 +- `__init__.py` 注册路径为 `ops.user.unstructuredio.process`。 diff --git a/runtime/ops/mapper/unstructuredio/operator_src/__init__.py b/runtime/ops/mapper/unstructuredio/operator_src/__init__.py new file mode 100644 index 00000000..d43c4e5f --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/__init__.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- + +from datamate.core.base_op import OPERATORS + +OPERATORS.register_module( + module_name="UnstructuredIOMapper", + module_path="ops.user.unstructuredio.process", +) diff --git a/runtime/ops/mapper/unstructuredio/operator_src/metadata.yml b/runtime/ops/mapper/unstructuredio/operator_src/metadata.yml new file mode 100644 index 00000000..3d689355 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/metadata.yml @@ -0,0 +1,93 @@ +name: 'UnstructuredIO 文档解析' +description: '基于 unstructured 的文档结构化解析算子,输出 unstructured 兼容 JSON。' +language: 'python' +vendor: 'huawei' +raw_id: 'UnstructuredIOMapper' +version: '1.0.0' +modal: 'text' +inputs: 'text' +outputs: 'text' +types: + - 'cleaning' + - 'annotation' +release: + - '首次发布' + - '支持 PDF、DOCX、DOC 及 unstructured 可识别文档格式' + - '输出 unstructured 兼容元素 JSON,并补充 DOCX 快路径与 PDF 噪声抑制' +metrics: + - name: '输出形态' + metric: 'unstructured-compatible JSON' + - name: '表格保留' + metric: '保留 Table / text_as_html 字段' + - name: 'PDF 稳定性' + metric: '支持 fast/auto/hi_res 策略切换' +runtime: + memory: 2147483648 + cpu: 1 + gpu: 0 + npu: 0 +settings: + exportType: + name: '导出格式' + description: '默认导出为 JSON;也可导出 JSONL 或纯文本预览。' + type: 'select' + defaultVal: 'json' + required: false + options: + - label: 'JSON' + value: 'json' + - label: 'JSONL' + value: 'jsonl' + - label: 'TXT' + value: 'txt' + pdfStrategy: + name: 'PDF 策略' + description: 'auto 最接近 unstructured 默认行为;fast 更快;hi_res 更重。' + type: 'radio' + defaultVal: 'auto' + required: false + options: + - label: 'Auto' + value: 'auto' + - label: 'Fast' + value: 'fast' + - label: 'HiRes' + value: 'hi_res' + pdfInferTableStructure: + name: 'PDF 琛ㄦ牸缁撴瀯' + description: '涓?PDF 寮€鍚?Table / text_as_html 鎺ㄦ柇锛屼紭鍏堜繚鎸?unstructured 杈撳嚭褰㈡€併€?' + type: 'switch' + defaultVal: 'true' + required: false + checkedLabel: '寮€鍚?' + unCheckedLabel: '鍏抽棴' + enableDocxFastpath: + name: 'DOCX 快路径' + description: '优先使用兼容型 DOCX 快路径,失败时自动回退到 unstructured 原生解析。' + type: 'switch' + defaultVal: 'true' + required: false + checkedLabel: '开启' + unCheckedLabel: '关闭' + suppressPdfNoise: + name: 'PDF 噪声抑制' + description: '仅过滤首页明显竖排边缘乱码,尽量少误杀。' + type: 'switch' + defaultVal: 'true' + required: false + checkedLabel: '开启' + unCheckedLabel: '关闭' + fallbackToAuto: + name: 'PDF 自动回退' + description: '当 fast 路径结果过少时,自动回退到 auto 解析。' + type: 'switch' + defaultVal: 'true' + required: false + checkedLabel: '开启' + unCheckedLabel: '关闭' + jsonIndent: + name: 'JSON 缩进' + description: 'JSON 导出缩进空格数,默认 2。' + type: 'input' + defaultVal: '2' + required: false diff --git a/runtime/ops/mapper/unstructuredio/operator_src/process.py b/runtime/ops/mapper/unstructuredio/operator_src/process.py new file mode 100644 index 00000000..282d4e85 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/process.py @@ -0,0 +1,574 @@ +from __future__ import annotations + +import contextlib +import html +import json +import logging +import os +import tempfile +import time +from pathlib import Path +from typing import Any, Dict, Iterable + +from datamate.core.base_op import Mapper +from unstructured.partition.auto import partition as partition_auto + +try: + from unstructured.partition.doc import partition_doc +except ImportError: + partition_doc = None + +try: + from unstructured.partition.pdf import partition_pdf +except ImportError: + partition_pdf = None + +try: + from docx import Document + from docx.document import Document as DocxDocument + from docx.oxml.table import CT_Tbl + from docx.oxml.text.paragraph import CT_P + from docx.table import Table as DocxTable + from docx.text.paragraph import Paragraph +except ImportError: + Document = None + DocxDocument = None + CT_Tbl = None + CT_P = None + DocxTable = None + Paragraph = None + + +logger = logging.getLogger(__name__) +W_NS = "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}" +PDF_LAYOUT_MODEL_PATH = os.getenv( + "UNSTRUCTUREDIO_LAYOUT_MODEL_PATH", + "/models/unstructuredio/yolo_x_layout/yolox_l0.05.onnx", +) +PDF_TABLE_MODEL_PATH = os.getenv( + "UNSTRUCTUREDIO_TABLE_MODEL_PATH", + "/models/unstructuredio/table-transformer-structure-recognition", +) +IMAGE_PARTITION_EXTENSIONS = {"png", "jpg", "jpeg", "tif", "tiff", "bmp"} +DOCX_COORDINATE_WIDTH = 1224 +DOCX_COORDINATE_HEIGHT = 1584 +DOCX_LEFT_MARGIN = 96 +DOCX_TOP_MARGIN = 72 +DOCX_CONTENT_WIDTH = DOCX_COORDINATE_WIDTH - DOCX_LEFT_MARGIN * 2 +DOCX_BOTTOM_MARGIN = 96 +YOLOX_LABEL_MAP = { + 0: "Caption", + 1: "Footnote", + 2: "Formula", + 3: "ListItem", + 4: "PageFooter", + 5: "PageHeader", + 6: "Picture", + 7: "SectionHeader", + 8: "Table", + 9: "Text", + 10: "Title", +} + + +def _as_bool(value: Any, default: bool) -> bool: + if value is None: + return default + if isinstance(value, bool): + return value + return str(value).strip().lower() in {"1", "true", "yes", "on"} + + +def _as_int(value: Any, default: int) -> int: + try: + return int(value) + except (TypeError, ValueError): + return default + + +def _as_language_list(value: Any, default: list[str]) -> list[str]: + if value is None: + return list(default) + if isinstance(value, str): + parts = [part.strip() for part in value.split(",")] + languages = [part for part in parts if part] + return languages or list(default) + if isinstance(value, (list, tuple, set)): + languages = [str(item).strip() for item in value if str(item).strip()] + return languages or list(default) + return list(default) + + +def _render_txt(elements: Iterable[Dict[str, Any]]) -> str: + sections = [] + for item in elements: + sections.append(f"[{item['index']}] [{item['category']}] {item['text']}".rstrip()) + if item.get("text_as_html"): + sections.append(f"HTML: {item['text_as_html']}") + return "\n\n".join(sections) + + +@contextlib.contextmanager +def _pdf_runtime_overrides(): + temp_json_path = None + env_backup = { + "UNSTRUCTURED_DEFAULT_MODEL_INITIALIZE_PARAMS_JSON_PATH": os.environ.get( + "UNSTRUCTURED_DEFAULT_MODEL_INITIALIZE_PARAMS_JSON_PATH" + ), + "UNSTRUCTURED_HI_RES_MODEL_NAME": os.environ.get("UNSTRUCTURED_HI_RES_MODEL_NAME"), + "HF_HUB_OFFLINE": os.environ.get("HF_HUB_OFFLINE"), + "TRANSFORMERS_OFFLINE": os.environ.get("TRANSFORMERS_OFFLINE"), + } + tables_module = None + default_table_model = None + original_load_agent = None + + try: + with tempfile.NamedTemporaryFile( + mode="w", encoding="utf-8", suffix=".json", delete=False + ) as handle: + json.dump({"model_path": PDF_LAYOUT_MODEL_PATH, "label_map": YOLOX_LABEL_MAP}, handle) + temp_json_path = handle.name + + os.environ["UNSTRUCTURED_DEFAULT_MODEL_INITIALIZE_PARAMS_JSON_PATH"] = temp_json_path + os.environ["UNSTRUCTURED_HI_RES_MODEL_NAME"] = "yolox" + os.environ["HF_HUB_OFFLINE"] = "1" + os.environ["TRANSFORMERS_OFFLINE"] = "1" + + try: + from unstructured_inference.models import tables as tables_module # type: ignore + + default_table_model = getattr(tables_module, "DEFAULT_MODEL", None) + original_load_agent = getattr(tables_module, "load_agent", None) + original_initialize = getattr(tables_module.UnstructuredTableTransformerModel, "initialize", None) + if default_table_model is not None: + tables_module.DEFAULT_MODEL = PDF_TABLE_MODEL_PATH + if callable(original_load_agent): + from transformers import DetrImageProcessor, TableTransformerForObjectDetection + + def _initialize_table_model_local(self, model=None, device="cpu"): + self.device = device + self.feature_extractor = DetrImageProcessor.from_pretrained( + PDF_TABLE_MODEL_PATH, + local_files_only=True, + ) + self.model = TableTransformerForObjectDetection.from_pretrained( + PDF_TABLE_MODEL_PATH, + local_files_only=True, + use_pretrained_backbone=False, + ) + self.model.eval() + self.model = self.model.to(device) + + def _load_agent_with_local_model(): + if getattr(tables_module.tables_agent, "model", None) is None: + _initialize_table_model_local( + tables_module.tables_agent, + PDF_TABLE_MODEL_PATH, + device="cpu", + ) + + if original_initialize is not None: + tables_module.UnstructuredTableTransformerModel.initialize = _initialize_table_model_local + tables_module.load_agent = _load_agent_with_local_model + except Exception as exc: + logger.warning("Unable to override unstructured table model path: %s", exc) + + yield + finally: + if tables_module is not None: + if default_table_model is not None: + tables_module.DEFAULT_MODEL = default_table_model + if original_load_agent is not None: + tables_module.load_agent = original_load_agent + if "original_initialize" in locals() and original_initialize is not None: + tables_module.UnstructuredTableTransformerModel.initialize = original_initialize + for key, value in env_backup.items(): + if value is None: + os.environ.pop(key, None) + else: + os.environ[key] = value + if temp_json_path: + with contextlib.suppress(FileNotFoundError): + os.unlink(temp_json_path) + + +def _element_to_dict(index: int, element: Any) -> Dict[str, Any]: + metadata = getattr(element, "metadata", None) + coordinates = getattr(metadata, "coordinates", None) if metadata else None + return { + "index": index, + "category": getattr(element, "category", element.__class__.__name__), + "text": str(getattr(element, "text", str(element))), + "page_number": getattr(metadata, "page_number", None) if metadata else None, + "coordinates": str(coordinates) if coordinates is not None else None, + "text_as_html": getattr(metadata, "text_as_html", None) if metadata else None, + } + + +def _serialize_elements(elements: Iterable[Any]) -> list[Dict[str, Any]]: + return [_element_to_dict(index, element) for index, element in enumerate(elements)] + + +def _looks_like_rotated_margin_noise(text: str) -> bool: + compact = text.replace(" ", "") + if len(compact) < 4: + return False + tokens = text.split() + if len(tokens) < 4: + return False + alnum_chars = [ch for ch in compact if ch.isalnum()] + if len(alnum_chars) < 3: + return False + single_char_ratio = sum(1 for token in tokens if len(token) == 1) / max(len(tokens), 1) + unique_ratio = len(set(compact.lower())) / max(len(compact), 1) + alpha_num_ratio = sum(1 for ch in compact if ch.isalnum()) / max(len(compact), 1) + has_word = any(len(token) >= 4 and token.isalpha() for token in tokens) + long_token_count = sum(1 for token in tokens if len(token) >= 2) + return ( + not has_word + and single_char_ratio >= 0.6 + and unique_ratio >= 0.5 + and alpha_num_ratio >= 0.45 + and long_token_count <= 1 + ) + + +def _looks_like_left_margin_strip(coordinates: str | None) -> bool: + if not coordinates: + return False + return "PixelSpace" in coordinates and "((" in coordinates + + +def _filter_obvious_pdf_noise(items: list[Dict[str, Any]]) -> list[Dict[str, Any]]: + filtered = [] + for item in items: + if item.get("page_number") != 1: + filtered.append(item) + continue + text = str(item.get("text") or "").strip() + if not _looks_like_rotated_margin_noise(text): + filtered.append(item) + continue + if not _looks_like_left_margin_strip(item.get("coordinates")): + filtered.append(item) + continue + return filtered + + +def _normalize_paragraph_text(text: str) -> str: + return " ".join(text.split()).strip() + + +def _classify_paragraph(text: str, index: int, paragraph: Paragraph) -> str: + compact = text.strip() + if not compact: + return "NarrativeText" + + style_name = "" + try: + style_name = (paragraph.style.name or "").lower() + except Exception: + style_name = "" + + if style_name.startswith("heading") or "title" in style_name: + return "Title" + if compact.isupper() and len(compact) > 20: + return "UncategorizedText" + if compact.lower().startswith("date:"): + return "UncategorizedText" + if index == 0 and len(compact) <= 80: + return "Title" + if len(compact) <= 60 and compact.count(".") <= 1: + return "Title" + return "NarrativeText" + + +def _iter_block_items(parent: DocxDocument): + parent_elm = parent.element.body + for child in parent_elm.iterchildren(): + if isinstance(child, CT_P): + yield Paragraph(child, parent) + elif isinstance(child, CT_Tbl): + yield DocxTable(child, parent) + + +def _iter_paragraph_chunks(paragraph: Paragraph): + text_parts: list[str] = [] + for node in paragraph._element.iter(): + tag = node.tag + if tag == f"{W_NS}t": + text_parts.append(node.text or "") + continue + if tag == f"{W_NS}tab": + text_parts.append("\t") + continue + if tag == f"{W_NS}br" and node.get(f"{W_NS}type") == "page": + text = _normalize_paragraph_text("".join(text_parts)) + if text: + yield "text", text + yield "page_break", "" + text_parts = [] + continue + if tag == f"{W_NS}lastRenderedPageBreak": + text = _normalize_paragraph_text("".join(text_parts)) + if text: + yield "text", text + yield "page_break", "" + text_parts = [] + tail_text = _normalize_paragraph_text("".join(text_parts)) + if tail_text: + yield "text", tail_text + + +def _table_rows(table: DocxTable) -> list[list[str]]: + rows: list[list[str]] = [] + for row in table.rows: + rows.append([_normalize_paragraph_text(cell.text) for cell in row.cells]) + return rows + + +def _table_to_text(rows: list[list[str]]) -> str: + rendered_rows = [] + for row in rows: + rendered_rows.append(" ".join(cell for cell in row if cell)) + return "\n".join(row for row in rendered_rows if row.strip()) + + +def _table_to_html(rows: list[list[str]]) -> str | None: + rows = [row for row in rows if any(cell for cell in row)] + if not rows: + return None + head_html = "".join(f"{html.escape(cell)}" for cell in rows[0]) + if len(rows) == 1: + return f"\n\n{head_html}\n\n
" + body_rows = [] + for row in rows[1:]: + body_rows.append("" + "".join(f"{html.escape(cell)}" for cell in row) + "") + return ( + "\n\n" + + head_html + + "\n\n\n" + + "\n".join(body_rows) + + "\n\n
" + ) + + +def _docx_coordinate_string(left: int, top: int, right: int, bottom: int) -> str: + points = ( + (float(left), float(top)), + (float(left), float(bottom)), + (float(right), float(bottom)), + (float(right), float(top)), + ) + return ( + "CoordinatesMetadata(" + f"points={points}, " + f"system=PixelSpace(width={DOCX_COORDINATE_WIDTH}, height={DOCX_COORDINATE_HEIGHT})" + ")" + ) + + +def _estimate_docx_block_height(category: str, text: str, table_rows: int = 0) -> int: + normalized = (text or "").strip() + char_count = len(normalized) + line_count = max(1, sum(1 for line in normalized.splitlines() if line.strip())) + if category == "Table": + return max(72, 28 * max(table_rows, line_count)) + if category == "Title": + return min(140, 34 + line_count * 20 + char_count // 18) + if category == "UncategorizedText": + return min(110, 28 + line_count * 18 + char_count // 24) + return min(160, 26 + line_count * 18 + char_count // 26) + + +def _estimate_docx_block_width(category: str, text: str) -> int: + normalized = (text or "").strip() + if category == "Table": + return DOCX_CONTENT_WIDTH + if category == "Title": + return min(DOCX_CONTENT_WIDTH, max(320, len(normalized) * 9)) + return min(DOCX_CONTENT_WIDTH, max(280, len(normalized) * 8)) + + +def _assign_docx_coordinates( + *, + page_number: int, + category: str, + text: str, + page_offsets: dict[int, int], + table_rows: int = 0, +) -> str: + current_top = page_offsets.get(page_number, DOCX_TOP_MARGIN) + height = _estimate_docx_block_height(category, text, table_rows=table_rows) + max_top = DOCX_COORDINATE_HEIGHT - DOCX_BOTTOM_MARGIN - height + top = min(current_top, max_top) + if top < DOCX_TOP_MARGIN: + top = DOCX_TOP_MARGIN + bottom = min(DOCX_COORDINATE_HEIGHT - DOCX_BOTTOM_MARGIN, top + height) + width = _estimate_docx_block_width(category, text) + right = min(DOCX_COORDINATE_WIDTH - DOCX_LEFT_MARGIN, DOCX_LEFT_MARGIN + width) + page_offsets[page_number] = bottom + 16 + return _docx_coordinate_string(DOCX_LEFT_MARGIN, top, right, bottom) + + +def _extract_docx_fastpath(file_path: Path) -> list[Dict[str, Any]]: + if Document is None: + return [] + document = Document(str(file_path)) + elements: list[Dict[str, Any]] = [] + current_page = 1 + paragraph_index = 0 + page_offsets: dict[int, int] = {} + for block in _iter_block_items(document): + if isinstance(block, Paragraph): + for chunk_type, chunk_text in _iter_paragraph_chunks(block): + if chunk_type == "page_break": + current_page += 1 + continue + elements.append( + { + "index": len(elements), + "category": _classify_paragraph(chunk_text, paragraph_index, block), + "text": chunk_text, + "page_number": current_page, + "coordinates": _assign_docx_coordinates( + page_number=current_page, + category=_classify_paragraph(chunk_text, paragraph_index, block), + text=chunk_text, + page_offsets=page_offsets, + ), + "text_as_html": None, + } + ) + paragraph_index += 1 + continue + if isinstance(block, DocxTable): + rows = _table_rows(block) + table_text = _table_to_text(rows) + if not table_text: + continue + elements.append( + { + "index": len(elements), + "category": "Table", + "text": table_text, + "page_number": current_page, + "coordinates": _assign_docx_coordinates( + page_number=current_page, + category="Table", + text=table_text, + page_offsets=page_offsets, + table_rows=len(rows), + ), + "text_as_html": _table_to_html(rows), + } + ) + return elements + + +class UnstructuredIOMapper(Mapper): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.export_type = str(kwargs.get("exportType", "json") or "json").strip().lower() + self.pdf_strategy = str(kwargs.get("pdfStrategy", "auto") or "auto").strip().lower() + self.pdf_infer_table_structure = _as_bool(kwargs.get("pdfInferTableStructure", True), True) + self.enable_docx_fastpath = _as_bool(kwargs.get("enableDocxFastpath", True), True) + self.suppress_pdf_noise = _as_bool(kwargs.get("suppressPdfNoise", True), True) + self.fallback_to_auto = _as_bool(kwargs.get("fallbackToAuto", True), True) + self.json_indent = max(0, _as_int(kwargs.get("jsonIndent", 2), 2)) + self.pdf_languages = _as_language_list(kwargs.get("pdfLanguages"), ["chi_sim", "eng"]) + + def execute(self, sample: Dict[str, Any]) -> Dict[str, Any]: + start = time.perf_counter() + file_path = Path(sample[self.filepath_key]) + file_type = str(sample.get(self.filetype_key) or file_path.suffix.lstrip(".")).lower() + elements, mode = self._extract_elements(file_path, file_type) + if file_type == "pdf" and self.suppress_pdf_noise: + elements = _filter_obvious_pdf_noise(elements) + for index, item in enumerate(elements): + item["index"] = index + + payload = self._build_payload(file_path, elements, mode, time.perf_counter() - start) + sample[self.text_key] = self._render_output(payload) + sample[self.target_type_key] = self.export_type if self.export_type in {"json", "jsonl", "txt"} else "json" + return sample + + def _extract_elements(self, file_path: Path, file_type: str) -> tuple[list[Dict[str, Any]], str]: + if file_type == "docx" and self.enable_docx_fastpath: + try: + elements = _extract_docx_fastpath(file_path) + except Exception as exc: + logger.warning("DOCX fast path failed for %s: %s", file_path.name, exc) + elements = [] + if elements: + return elements, "docx-fastpath" + + if file_type == "pdf": + return self._extract_pdf(file_path) + + if file_type == "doc" and partition_doc is not None: + return _serialize_elements(partition_doc(filename=str(file_path))), "partition-doc" + + if file_type in IMAGE_PARTITION_EXTENSIONS: + with _pdf_runtime_overrides(): + return _serialize_elements(partition_auto(filename=str(file_path))), "partition-auto-image" + + return _serialize_elements(partition_auto(filename=str(file_path))), "partition-auto" + + def _extract_pdf(self, file_path: Path) -> tuple[list[Dict[str, Any]], str]: + pdf_kwargs = { + "filename": str(file_path), + "strategy": self.pdf_strategy, + "infer_table_structure": self.pdf_infer_table_structure, + "languages": self.pdf_languages, + } + auto_kwargs = { + "filename": str(file_path), + "languages": self.pdf_languages, + } + if partition_pdf is None: + return _serialize_elements(partition_auto(**auto_kwargs)), "partition-auto" + + with _pdf_runtime_overrides(): + elements = partition_pdf(**pdf_kwargs) + serialized = _serialize_elements(elements) + if self.pdf_strategy == "fast" and self.fallback_to_auto and self._needs_pdf_fallback(serialized): + fallback_kwargs = dict(pdf_kwargs) + fallback_kwargs["strategy"] = "auto" + with _pdf_runtime_overrides(): + return _serialize_elements(partition_pdf(**fallback_kwargs)), "pdf-fast-fallback-auto" + return serialized, f"pdf-{self.pdf_strategy}" + + @staticmethod + def _needs_pdf_fallback(elements: list[Dict[str, Any]]) -> bool: + text_chars = sum(len(str(item.get("text") or "")) for item in elements) + return len(elements) < 3 or text_chars < 80 + + def _render_output(self, payload: Dict[str, Any]) -> str: + if self.export_type == "txt": + return _render_txt(payload["elements"]) + if self.export_type == "jsonl": + return "\n".join(json.dumps(item, ensure_ascii=False) for item in payload["elements"]) + return json.dumps(payload, ensure_ascii=False, indent=self.json_indent) + + @staticmethod + def _build_payload( + file_path: Path, + elements: list[Dict[str, Any]], + mode: str, + duration_seconds: float, + ) -> Dict[str, Any]: + table_count = sum(1 for item in elements if item.get("category") == "Table") + table_html_count = sum( + 1 for item in elements if item.get("category") == "Table" and item.get("text_as_html") + ) + return { + "input_file": file_path.name, + "mode": mode, + "duration_seconds": round(duration_seconds, 2), + "element_count": len(elements), + "table_count": table_count, + "table_html_count": table_html_count, + "elements": elements, + } diff --git a/runtime/ops/mapper/unstructuredio/operator_src/requirements.txt b/runtime/ops/mapper/unstructuredio/operator_src/requirements.txt new file mode 100644 index 00000000..cb803ce8 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/requirements.txt @@ -0,0 +1,2 @@ +unstructured +python-docx diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/check_docx_fastpath_coordinates.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/check_docx_fastpath_coordinates.py new file mode 100644 index 00000000..fd70300e --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/tests/check_docx_fastpath_coordinates.py @@ -0,0 +1,76 @@ +import importlib.util +import sys +import types +from pathlib import Path + + +def _load_process_module(): + if "datamate" not in sys.modules: + datamate = types.ModuleType("datamate") + core = types.ModuleType("datamate.core") + base_op = types.ModuleType("datamate.core.base_op") + + class _Mapper: + def __init__(self, *args, **kwargs): + self.filepath_key = "filepath" + self.filetype_key = "filetype" + self.text_key = "text" + self.target_type_key = "target_type" + + base_op.Mapper = _Mapper + base_op.OPERATORS = [] + core.base_op = base_op + datamate.core = core + sys.modules["datamate"] = datamate + sys.modules["datamate.core"] = core + sys.modules["datamate.core.base_op"] = base_op + + if "unstructured" not in sys.modules: + unstructured = types.ModuleType("unstructured") + partition = types.ModuleType("unstructured.partition") + auto = types.ModuleType("unstructured.partition.auto") + + def _partition(*args, **kwargs): + raise NotImplementedError("partition stub should not be used in docx fastpath checks") + + auto.partition = _partition + partition.auto = auto + unstructured.partition = partition + sys.modules["unstructured"] = unstructured + sys.modules["unstructured.partition"] = partition + sys.modules["unstructured.partition.auto"] = auto + + module_path = Path(__file__).resolve().parents[1] / "process.py" + spec = importlib.util.spec_from_file_location("unstructuredio_process", module_path) + module = importlib.util.module_from_spec(spec) + assert spec is not None and spec.loader is not None + spec.loader.exec_module(module) + return module + + +def main(): + process = _load_process_module() + base = Path(__file__).resolve().parents[2] / "test_cases" / "example_input" + samples = [ + "docx_corpus_sample_1.docx", + "docx_corpus_sample_2.docx", + ] + failures = [] + for sample in samples: + elements = process._extract_docx_fastpath(base / sample) + if not elements: + failures.append(f"{sample}: no elements") + continue + if not any(item.get("coordinates") for item in elements): + failures.append(f"{sample}: all coordinates are null") + if not all(item.get("page_number") is not None for item in elements): + failures.append(f"{sample}: contains null page_number") + + if failures: + raise SystemExit("\n".join(failures)) + + print("docx fastpath coordinate checks passed") + + +if __name__ == "__main__": + main() diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_docx_fastpath_coordinates.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_docx_fastpath_coordinates.py new file mode 100644 index 00000000..26eff009 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_docx_fastpath_coordinates.py @@ -0,0 +1,71 @@ +import importlib.util +import sys +import types +from pathlib import Path + + +def _load_process_module(): + if "datamate" not in sys.modules: + datamate = types.ModuleType("datamate") + core = types.ModuleType("datamate.core") + base_op = types.ModuleType("datamate.core.base_op") + + class _Mapper: + def __init__(self, *args, **kwargs): + self.filepath_key = "filepath" + self.filetype_key = "filetype" + self.text_key = "text" + self.target_type_key = "target_type" + + base_op.Mapper = _Mapper + core.base_op = base_op + datamate.core = core + sys.modules["datamate"] = datamate + sys.modules["datamate.core"] = core + sys.modules["datamate.core.base_op"] = base_op + + if "unstructured" not in sys.modules: + unstructured = types.ModuleType("unstructured") + partition = types.ModuleType("unstructured.partition") + auto = types.ModuleType("unstructured.partition.auto") + + def _partition(*args, **kwargs): + raise NotImplementedError("partition stub should not be used in docx fastpath tests") + + auto.partition = _partition + partition.auto = auto + unstructured.partition = partition + sys.modules["unstructured"] = unstructured + sys.modules["unstructured.partition"] = partition + sys.modules["unstructured.partition.auto"] = auto + + module_path = Path(__file__).resolve().parents[1] / "process.py" + spec = importlib.util.spec_from_file_location("unstructuredio_process", module_path) + module = importlib.util.module_from_spec(spec) + assert spec is not None and spec.loader is not None + spec.loader.exec_module(module) + return module + + +process = _load_process_module() +TEST_INPUT_DIR = Path(__file__).resolve().parents[2] / "test_cases" / "example_input" + + +def _extract(sample_name: str): + return process._extract_docx_fastpath(TEST_INPUT_DIR / sample_name) + + +def test_docx_corpus_sample_1_coordinates_are_not_all_null(): + elements = _extract("docx_corpus_sample_1.docx") + + assert elements + assert any(item.get("coordinates") for item in elements) + assert all(item.get("page_number") is not None for item in elements) + + +def test_docx_corpus_sample_2_coordinates_are_not_all_null(): + elements = _extract("docx_corpus_sample_2.docx") + + assert elements + assert any(item.get("coordinates") for item in elements) + assert any(item.get("category") == "Table" for item in elements) diff --git a/runtime/ops/mapper/unstructuredio/test_cases/README.md b/runtime/ops/mapper/unstructuredio/test_cases/README.md new file mode 100644 index 00000000..38bec69b --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/test_cases/README.md @@ -0,0 +1,36 @@ +# unstructuredio 测试用例 + +本目录提供公开可下载的 PDF 和 DOCX 样本,用于验收平台复测文档解析算子。 + +## 公开样本来源 + +- `example_input/attention_is_all_you_need.pdf` + arXiv 论文 *Attention Is All You Need*: + +- `example_input/bert_pretraining.pdf` + arXiv 论文 *BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding*: + +- `example_input/docx_corpus_sample_1.docx` + 公开 `docx-corpus` 样本: + + +- `example_input/docx_corpus_sample_2.docx` + 公开 `docx-corpus` 样本: + + + +## 平台测试步骤 + +1. 在 DataMate 算子市场上传 `../unstructuredio.zip`。 +2. 创建任务并上传 `example_input/` 下任一 PDF 或 DOCX 文件。 +3. 对 PDF 样本建议使用默认 `pdfStrategy=auto` 和 `pdfInferTableStructure=true`。 +4. 运行任务并下载输出 JSON。 + +## 检查项 + +- 输出文件非空,JSON 可解析。 +- 元素至少包含 `category`、`text`、`page_number`、`coordinates` 字段。 +- PDF 输出的 `page_number` 不应全部为 `1`。 +- PDF 标题、正文、表格标题附近文本应可读。 +- DOCX 输出的标题、段落、表格顺序应基本合理。 +- DOCX 的 `coordinates` 不应全部为空。 diff --git a/runtime/ops/mapper/unstructuredio/test_cases/cases.json b/runtime/ops/mapper/unstructuredio/test_cases/cases.json new file mode 100644 index 00000000..587438ad --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/test_cases/cases.json @@ -0,0 +1,74 @@ +[ + { + "id": "pdf_arxiv_transformer", + "operator": "unstructuredio", + "dataset": "arXiv", + "document_type": "pdf", + "sample_file": "example_input/attention_is_all_you_need.pdf", + "purpose": "验证学术 PDF 的多页解析、页码覆盖、坐标完整性与表格识别能力。", + "source_urls": [ + "https://arxiv.org/pdf/1706.03762.pdf", + "https://arxiv.org/abs/1706.03762" + ], + "checks": [ + "输出 JSON 非空", + "page_number 不能全部为 1", + "coordinates 非空率 >= 90%", + "应包含正文块且存在表格相关内容" + ] + }, + { + "id": "pdf_arxiv_bert", + "operator": "unstructuredio", + "dataset": "arXiv", + "document_type": "pdf", + "sample_file": "example_input/bert_pretraining.pdf", + "purpose": "验证另一份公开论文 PDF 的通用解析稳定性,避免只对单篇样本适配。", + "source_urls": [ + "https://arxiv.org/pdf/1810.04805.pdf", + "https://arxiv.org/abs/1810.04805" + ], + "checks": [ + "输出 JSON 非空", + "应覆盖多页", + "主要标题与正文文本可读", + "coordinates 非空率 >= 90%" + ] + }, + { + "id": "docx_corpus_sample_1", + "operator": "unstructuredio", + "dataset": "docx-corpus", + "document_type": "docx", + "sample_file": "example_input/docx_corpus_sample_1.docx", + "purpose": "验证 DOCX 原生链路的段落、表格顺序和 coordinates 补全能力。", + "source_urls": [ + "https://docxcorp.us/", + "https://docxcorp.us/documents/00042714bec87fe8097f604fdd230760c956aac77fa56fcd5bc5ffb68c60690a.docx" + ], + "checks": [ + "输出 JSON 非空", + "标题、段落、表格顺序应基本合理", + "coordinates 不能全部为空", + "不应整份文档全部落在第一页" + ] + }, + { + "id": "docx_corpus_sample_2", + "operator": "unstructuredio", + "dataset": "docx-corpus", + "document_type": "docx", + "sample_file": "example_input/docx_corpus_sample_2.docx", + "purpose": "验证表格较多的 DOCX 样本在输出形态上仍与 unstructured 兼容。", + "source_urls": [ + "https://docxcorp.us/", + "https://docxcorp.us/documents/000e366a02330e96ce5e878a2c2ecceba7374715a1065a5ece914d024a25d951.docx" + ], + "checks": [ + "输出 JSON 非空", + "表格附近文本不应全部退化为普通叙述块", + "coordinates 不能全部为空", + "文本顺序应与原文大体一致" + ] + } +] diff --git a/runtime/ops/mapper/unstructuredio/test_cases/example_input/attention_is_all_you_need.pdf b/runtime/ops/mapper/unstructuredio/test_cases/example_input/attention_is_all_you_need.pdf new file mode 100644 index 0000000000000000000000000000000000000000..97d7c51c5d8901e87995a89589b8e91e21459728 GIT binary patch literal 2215244 zcmd?QbyU<*^e>8mD2OQCAP7j82m=hDB1j0*9ny&8(5(VWi=+YrN(_y3cOx)#hvYEy z&^_-vqyFN)_1?Pgt-IEJYd!v%@2P$E*=NV+>~mmwB`w3v&m)A-5{b_*D9p&mXm9cc zUtFA#SH}9Sv$+%S`}Vc7xwN^dy_q>9ucEn~rLz^|BR+n9MhOXgh_jRVYg>Hx$ueDq z=%wT^+bDps~T@nt7oPL+j)nD0~dKArPf5DSZ z#%+Wb)eOHM@;N(DsqFEiCqqqIqRO*tuiq#^^oZ~@SR#i#@`--P`+{#qYp;0}#YrC9 z#C6S&GBLPBjXUNTOdp ztWj=zt6bdsV{C&S9O0kjwuH^3Iby@Ip+hYyHp$)z_O7dzgFm_QyI{mL z+2iUDyu;fh#Z=-r594}X6*UL+jVt+4mBP-uwKKXmN=-Wpt>D4 zOcVaTj{ea^cjG6CIm6Sq{8|Q@^c7?m)7}VE;+>T=eiOoPo8qt8QkaJ3`LDYZ%fWWa zMc==FIKJX$3qf|e`roU4O16n}=Cwx8cGhlSc0RJ=@M3CuV^Ne&Bm*w(QIt&A+1sey zD_Br}O%$1~;bhxqIpvX&-&|sry8LwKb-ztGX^K?ThvTIN9Lu~C@yoSt1}QgPvYb|; zMw5dUmGtUC(%Z1)EDAf^7_N@Hq)Hn~`JHl9NTr*Fg%AXo#<`m0DX-&XYHkUh^%oNmeTT)Tf9%xmI|nZ2oa;R{PWsr6lCJ z=G?6AdLuEh5e>zy?czxXShwre2lI z->fg2q&CDvWGmW36Tt@S1yuI5>f|qEv>B4fJg(jWB_Cx)msAjB(5x!oYP$xeQ>Zo_ zk8>0Z`o>87>#myV3+5DViY(u0Txyy3dRR_eH2YdNO_9u_jLsrTlltC|gW){>_tfty zLUz=?&BLSN9_3uD)Wu3LZ5Uu*~bg!*Ihw;V} zd)ly0D*R@WdZ;eV(L1h5A=cMYNqF?T>ys-^<|QX3{yoiQzUO;>YWmaUY$bROimBet zH@jlHw%3PX1S71LIh-@h7sb;z^)y&}OK%1e-rF4Xs@xDPZhES($23bmWvvf5?xZfElP_q=_4sz~x>^w}a&=Vc&^%c( z3V8Df1@L1wyK3!;Qp@3Fa1$B6s)g%gUR%G@05OdajgUu5aW<2@_o}3}M3^iNo>S^L zyjSJ%4V>+iFz>>1b6z6M;7#gsYGXOBE8G-G*MDXF@9-&Ax!aQFd(Q6px*TMmg+@~DN{>4d`94g} zsNNO6Ng}WJ&Wc~+_4;%zlc4_XL_K<$qAW#LZrW7S>W9ZBa3}X~H%^*U@Xp)E2p@BG zt1oHP@;Yi!X_+H?M42GCo9|;rHut(={#p5HS>ZKoVSz2Z5|(DM-vo|CZqPQU{rWOe z++*-CNGqO1^#Vtff}2<8*LV97CsN-)9iD)};7@OSzYt$J$Yy{YpINzZJ+jKX|GUw|e+wZ4V z*Anhry2uqg$y!$|CeG#%sXLx1FYH*Z)mNdp@6!HWh~lz;--^9wtFf2%+0vUNQI+ug zy|QvEk?ZAsi}!bTKfmAH967!I6mO-NSr+Fg+k*cztRl1HW^{Q{QP8qjiqVG_hQ8~s z$CBa~!oyiZuDwh$fIw>se%D4$^L=?ysi-yBo5t%L5a{*wL)VFZC&F;cj!0k$NGmk5%mt3TL4 zy5{;^Y@w7SGp?NN%H18&@lCWaqI+uic+6t{h6j<^Af!Ct0Vqgq=$@vc0VJ4yG1%f^*f04I!h2^ zA#KHMr;!#P z^6MkfM$>ukSg?x8=fnVWQLg6G(2_9;o|qq!8I2;viC&i7M?sHtxvsbfj%fa<_YU{d zawlS+DHJ$*%F!qlUz6@-&E%nRCM-<6C*vKyB+nH6# zgCsYh<6b}hdJc48qJPqDKJRIxcfC8VpAl%^*I>en?tHhI5C8t_ZJk?`QLKY1iT!rr*DhC{Mh#u^ zNuwroIYgF7F>7JUw@5HtN$7#;m4Sv2giFtNH!J3XM$#l%>)*n!##9B|YKC9lgIw0;lCT^vqZ^dGXN4`DN9LC*l1<;4ue70+ z*rYYmsc5;D{2RPj8M@x(ZBu@q7(K0(+cn}EguP2hXTE*a;50(^c=q}exY^ue_jaR? z^X8Rk2AiPTkJ|xFx56Zd*O%yrNbCD~iV+>lu6K!BdJCQ0dr8h4mz%Q3c!C(49JP8> zQ{w%E$~*Ti-qcwAIMWd86Eg_Y^WD3VnK=BL?sJ}$wY;AX@!i=@yEHWM zMWX6bY)C{rY%WE5Uh`z}MRlk2a%L4zprKa%35qFg`y|aCFyI;i1khV*ov7QQDe!r*?0|?(E#6LQ-5R=_E6lqqSE=Knmd-Lw#>_$}TK*lU7cT&G9@ZgKm|J zu^fm``PzMi9*%)|4L_ErL?c{_x2={-oo5K%1k2Aj=P>0HsH}zTgYNhc9o2A#h;OY? zh$%g~(Prg9xgr>D0rOF5Eth<6;E`uaU$lS96(7E=$FK}EaB z>i!{t8Y&|NI#ciaC=vaFmH^*YDqZ{rA=@9Xb~(4+ka29~!(vHeA5D4rtz4tgX?hHz zb#y&-jW@HVqOf02-&0J;8{f5~xxHdK6XihaYZAY7_mE+2@oTG_*`#BE&fE!=n(59B z<(F0{0WzJhLu5lvFEr~#^S$vCk1HN&ECv+CY49&w2a>nI&567%=mL@COLsXrqq*DVjCFqr=E}hqrX(Bh_cmhifilmpaiuDyucr(|+7Fp}DeD_et00Rmu3)>Ge2x zSb#{LrOAxvg!Tsx`nZ$oot$6h$6vS|Tt>PW{9?X;k4=3ZPo;I9vX-3F*tXLVA^8E? zkl}Hf%DN;UW4;18Zy+kj3g9Z8+abbVkNowWfcIEzg_wA_woUxwY|ZQ){RfwRHO&uy zy2j3Bhf-WE7N1 zakGf~J^G+3DGw)HoST#*IeB(x_9~D$zE}?FjH=h=f}^5&cZf}#wO&UB-eFse&VA5P zZiDc&SiQy_4aa`L^|G=VpP2S+KbPwrja=|hJ3(ljlFrN_GGUXIpJ#X z;#T?8ucpU@S04`Ftp+j5;W+fI*$_68j5%7xF%u|Nwb#IL>ggbuiNeoVD7e2Dk_ohie_SHH0 zH0fBU+x#XT0TRuo9(OE;rqZT`M(}rye^g~#Tao?lvQF(H4Ef!oL)tg;$o%2^m_n(0 zIF8xV_^7)fFXH!+?e1+;)NlIvv`*qY{GY$7rm?`ezH17XmvTRu#as4dgSTOdKN*ji-v&d4KGDeMU-59$yKoLRpt2;GJF_Y5UZ|#(Ft!I9YI5 zdtQnt3$9+o=e!WAw9zDu8w4-BJSVRESAEQgRDWl}qToW|W~JvD zfh^tmxp?RgQAb-e`fEsnpB8%0xvX|tbD$4rMUV^d&2c=@wo_{@3^NZMe@|y*Qv%{HIzvwNvN;}aexBaH*tyZ zGv7tLDxmxB^XfSDTP_)l&c?1dyiOPWh0gOR#34=Wnh(;R_xQ{LNk+hg14~XG?bDYe z*12MG)#^O1N7qcZZe)cxnQZ5V(2=rhoATjybGrM?t@n*T@H8_5mS~ItI1d~3t0X%f<;SK`MoDqMRHdTEkRxKX&EIDYoMDhlg+bI8^!@YpWe+l>M9u7cKUt8Jajk&2aBd?l^i8HoF z&i1t>(D2mS8S={9>6yK)gT0-(oin2dKJPR8xAsnI4zEptc4>20Yg2Po*{A;(w*@cE ztu3vb83hCcLHPf!4n#x*`S^gTUcQFdF!Bov0o*lD1hGMhvnCE4$Y`>_!YQ(j_ig@ylRf?e)PsiCov_{O!!qvjHZwv8(0smxe z_Cip>(7YZDS=lnc`Jego&!Eb1OvUt!vm5@jcmw$8Zy0E%eFl8^`-bTX?Fg@`Y0d&A z<5;CVk~2kDIoWQ9yO=Ty97Xf!tNxdWn0ZE^+_;wfo7bsW@;sf{T;wKD@zcceC_ib1 z2!wn=b>}KjkvBf!qlY;5RN_ggltcp+pAWKqYS@lj6h&2oJ^*DLPKe>$>BI$JVf7aQ z+Ur1t_Sd~rp1!SvqsvdDbmpobM3a8TOUVs33G2l;NP}%Q=M_ijxd!8)i zNc?g0H?Z-Cil6&fnzv=`VLP0o5Sj4(9miD=(EaD`e$ovvtVx-ro)?SFpk71mHlj7mcqu)^C0N|R6$}d<%S2%M z*e0JH?KpcJB;guO<;nI#fGYp;z6&q+>X9u_Ft0NF3Q#jCdbB-{6j%f0*Iq#Fcguc1 z!3@3e6pk!GOdG7doT3oNh^YFwQJV>g+_I$NB-7vK031(X!*rx?XrnU{C z3sPRdt8%gI=R+^uE~GvC4E{*N?{sb;+o!vv(&*$rYn0*E=ipGuUrTO>9-nr@bupZ# zIww05GZ_6N6OJ!cV|kQjty*6)!q6<+eMThu<*R30jz9rU80<+5rH>& z8Ec@?V}In3mH(!w^V(zI!)kb$I~-Y1dV7x%m;|R~SiVww$?+T5{sT-eU7(CuuUHH# zCu8n$9$hr*IrPzmEOkRR&+Hf<5k}4U%+fq`PonlMmC-9TU1N8-DYePZCusk)IizWp z9So1mJw7>jK5N`2Joi%X_E3ueOaj~dIS{JQ#{?HUu%z&a3)$9R`n}|Z(RKf@eI2K7 zU}PSH{*n$yeg4FH&jlk;k28T}TO9To%&0x8E`$hSwOmSOp9C|c7P}LeJ;Zd}{ehMA z(sQgTbcSMg^fLuk;EcT3O_DOi?#=%&5Ht9H;ooR$mPW3dRBe1Y)COh0^A!+SZ-cd-~dF_v%u9$DgP(~!}m`U83WyS*NWvCwwzKFFiY^CPug7v&HnnM zAiLtrM&apc2{4#;#rWZViGU6bK#&-V;Tu=;1p`yex2*~S#k>+8rIQ2N?TmGb zG%WeP{Ui-f)HB~dg1CJWBe||nu%E1Ekqv-l-OatNz-#1vB*6b*WkS{M1Uc7%a zIKvQZzPUHOpz;Rw0q|VLGy8K8YUvYrF`_j z+7_m(6kNvyp6wzb_9lITb9=Rl+?&_MR14j~JqI0{>6kf4VFB3OPtv3pTwbc)>U#U3 z(}pDd3*yGm9@2s|%& zFxV#CbGkxrc)lRp)z=OXa{h)Z8V+(hNa~ZQEWhI-D<=()at7*Gc?g`fumtuc^e@C! z#u#)`@ba4=`5y49slm-ffYsky0_6wVQ_zy*@aFaQQi-`xD8%g@G;I^ZpPs|&9@W@) zL}|TIXtH_O0UbixXv@QqFnZ@x!~LXv>Y;(yFrX=q2y9sewv1Bq z0<#T4hc-MeiUIRTO;fwvf;zGkR=hdt+g1>_a?{E}++MQ(k&aPKCRp_~kM^=PkS!ev z*peMD=b(Z43&uGsNJhIf?1n%NT_e-aVtJRPT=s>Z4+4A}2U`{^Y=d0JdTt*EQ@&2QhZ-$CJh;0B zOrkBkJ_=c3jVO2J%07@b5cf^lUbb5SwnWl^TLK$3q}E|Y7viQA);}t444zV*5_>6e z;<+|SQUcUwY>RDu{_v`?u^*vCC-fQD$Z~z`_(6U1?Ch_Z*mck*JqyM~`Ma9WK&rK8 z1;6Fb9E~r~WKTh=D|>8%!LWS$t*wVHKBk@kH={2B6+vY?o+^iPlpX8ag567?LkEuQ z3pAd`D_aq&i|NcOKsUaCk~W@lM84OT*-Av|v9t>uC3~xV?s32opdO_zt8u%sxldGW zY|fa0&YH>*V1(VIkZitl7;Z{#ja$_2qJlT?#Zgjud7<@T0s(nd8+sbEO$akoSXw4^ zZ7mNpD^|7u;LwW~e3VqlSD=PX^0heWXx(#wm zEO19IK&;JWZCEhtEgM8oIm#-R#zcEky+*+^4s34tVDQNQ<3Hy&`}VW|MI3+qzwv&(&J+Qd3h;sTkvLRTFC7#y69g@=1os6S$Q8YjpIiU?p@TGBDrhht`@ z-h~2G35SyUZvaX2pk)He{_~V94l$T6LC^ls=zRFq6hnjW`rjBM<07Ju>F`S^r|TY| z!8qDHe`qkL$ zPY%pGza{ZA=ll?meZK>aEk?pDc&}W5pBP#k4WKC1bL9aYP;8}@!btBf1P5E>$NP-& zi~zWl!*-H$ocp+iUVV4bo)DWdH!(Yk!5O=opc=QiGYZSg-7>cZ^r7S|Uwht2K*O;m z^lZ?Fq1p&TvGd`I_kQDLiuaD1Wm$XPUVzcnNQSdg%P> zN81xVQFms@2?^szsoUo)3UdHD>tw3ruu{bf@)Bxq-79OTGYbYBN#kd)h&E7rLKmh# zMrn)_zzDbUisTAvQ&vP8-r+h1476;3T%SH}S4?gY*^9?$fj`tV46Aef5Z#n9JMZnU zmT>WtVN2G?k@=3uAiskV`-a~SslXlE8o+R{<;}hP?fP1DKbwp-)Z?&+X1hTsiGslp z-V!NJ+|Ud$ItzghV~x$T4<8Oth*+a}D(JD|>$BdpSK;PaL1IGr3~H0PgrRuhQsVPl@G%IjHw(H!-grNB7`0J-y&x?)$V@>sSTp z7+IGU6|oh4RA)=x5mA_+uhQ0kR57>;lEIj5KSa~G{&bUqT;G_)$h|B^Np(M~s?Z3| z|3_LSSNE!5%4E4V)N^_qvtBTC#pl_y{~*oDcShu6f+8ichvgwCv8D@#rHJ{AP2Tbt zWlBk1I8^nF_$O{4q~yU*M%|2jS0)4(<>rVz&Mz|HCg|_V0lcFjPkj!Pc0MRe9DF^- z{kW)kQP9%BJu~HV&P>=mHq89kR}3F((y55N`2$U#+2l8GVjhCdj|a5;c9XLu4LLYU z0xIH;lcVE<$v!UY&G}S~i&T%hd*pQe5IC|8iXSt^RnH&es}I!iexmPra!XR1^e4+~ zq~RYC>?ei1>TjWr1QdeTj-dDIb2ONZMJk+Tc!^m(v4(4HB*mL8f`fhAbM1Ac>2Thw z$E9NNSVy`FD&dI@A$nd!n-S`9z&6Lu?dSolF2nM+5j$>5*K;l)Du}EE_(hn$I7SSr zh1JNaJZ+EHjJ@;Jy6EL`3fT!~1W2uL^K`Ak=pp#`u(>2E9NA*pXAnx(uwJQ##5yj2 zs9=^t!OBV?uGUH`KVoN5mh;O~J2r6&9H0(o<50@VAk4NU6d?lxl(YXhkQnc$eew-rM%3Wz2cL-HMFi`TcG3&D+GknpuUh zr&uSF3=3PBHo58%k1nb@UdQXqc?Lq9C{w%7g8Ejr;Qx_gw0mYGw1q4JQeu<+AA>=C zOA)PP!YT4qlx%lyx{P_%qAvB?G_*=~pN@gq_zl~B=@J*J^) zp*1QhTbWw*?N{nMWfxO3+~)O6{p+?PCZ8H*mzaXO2W3vl#uo%Obr3DlniLy z-0usohJG6^Id^=|63O?kzSn`1X4lKSSmQiE!a#oXl_6v&-LxK*ccjjoUl9!U_hqV$!K$@<8 zIGGVbBNw4q*Xwy&SGrG&u}A=fxXJ%|Du3mH;q^gxg}5ID7=Jffg799i;f2q@L~Cn~ zOROA%N88(>&$r|Y5rE%IMJ$!oC{16t*z_H$B+G-qv&YLHde>=Z47oQcPea~*$iwtn z1=$Fp24m9o53jXwb26eYgY}>XZjSr~I z9hZcmF1i=%f}3fSySU0cm69eG5XB6|n5Y1FK0tii3o*oa@`Ml8&-A!+5v?_}T3nsh z(~xGEk$$_7VKm^WmVKB1cqqZ1V6meJv1Rqs|G;sTV zKDrq7PN2REH7;Q?ZB4Mvv1l>G-*A5r9Qjs zmD&Jg!4_h1P&6nbO29Kch>6er5K)64LtMyKewfM0OMPNhrmkGc6D8V*99yUus6@yZ zpKujd1)^0?Bhp?%NO&b|PWRwI6IBixVJHoE{;T4@Nm5oK-CoM+f4NuBedp$g4M?8g z#T`lCQYN*4j^KtWQHk`UqDThOTzA~qX%@#{{8isw zdC}+HHw8WB)_|}nf9#1|gT^GO>N*MfhN!yUGz!+*y^eAJYad_wUCE%c;3!bi1vYOR zEnz1#AKSWa*6c`N6zny5{Gwe}#Jfc#Fyn2a>AxNALN(`hNk^}~%g+y4|1K{FD@}*# z$}44;jVQ8{6P6H`wVx=2NsZ$iE&SQ%!f5e+<|v)g$ty3>y!N3BOg6 zXoU~t+n_~DUZ>vAUVZNO`lch9y|1I*c`ja5$Zy+4nLo}5cP7qF#^|d*bO?>{Jd2_E znFSV9MrS0MqsbjG*VwL~B>-&5G+ZiMQGl`XI(Pxwzx$?a@Z)MfHgtGK@XNrlv2mZ) zwC6K|D3TTntAZvV7Mq49VLE#!$(y!VWb+e@u<`Ti%Fg9qLD$%v*US}O*3BPbp;2^% zLO~dRhR69h>;TBN`QJZE`rQLDa=L00Mg?CULzg4~Jo24GNzQvS2$W32`L*V%%e{{3 zFt#H_4rX%)1{!%Co%LCU>%dRC@Fer=Wvejj;_FEloK<2=8lo~Ceba1o-fDEuHy$|C z-2RCG3?ERhFLxL*CoD!JjtK@=rC&?MSo#Z5f6R7oX*aN@6s?QCq7zih>|jtv8H_pl>P5hvOw~%J*6;41@z2fmBo-U{*#CDuMJy+ z^kX{2ng7j9|K$2Z12}>>>|cL2o!^k4jP9%o@@_^i_7 zaY}$lf>WD9(WmCv5us4#6-v{==!m&2U=|>4LIf^_-^$}>g;r4*o@4;ok)N#zB;x3U zUwww*{26sv7YP^~Evx`IhGf?-#?Iwp25x{Dru_Ona``j2ShRc#fmN;o=alcg0GC)5 z0!n|OvZctLQGsuvNDiXmv{#dUZ!zV#1$B*H5`~EP`PVZ5u^(^~Sey=o^FNRuo3l6l zTeO!%2xzJMV~3(_iYhfq>9(pocE#WPI+zxFFO+Y$(H?qu!G}WJJr7 zpy$Hs)mO89aT+a~qP^6MO)+2?^4tQ=%gI_F`W!Q}6S(lyIh)693?q5_UOsChP`Wqk zK<8nd|Bk(ajaD-{$xBW>yC7z?C!phYAqPLS7Q-XI z<=jU}0S}axd*k3*atL0Smy-JqfYDQm{i6N=kc4+fNoueLkxRsyLdt@cNY!3XUMvV$ zHpk;Gc7u7Lb>J03yW5m} z)7;b)KFyg=%pj;F70p{#$;Bz|vOtq^#@rS~Wn?XMw9Ee&Nn2Qf*?bn~M8*^iywo|1;zzwtA(CC`9$N$icm z!`Z-h+d@CB9MXpVg~lCbV~{rnlw_Gd5TrHhkF@ty^EPkszHJhwpEIaC?Hqoi^KZFQ zo=P)^ssj+!Eek`(?On~$9@2GhRiHBN@6LAQsltPK+jL(oWN6G!h2$26c1a8kmEbM;BO4FpV^8<8HVp%{z#}r=0gSQ(1__wZ0K`Hg{+PRT7SbHbwH07U zTyK~+nC<1q`43u$9e{f6G!1=JG_0Q}xf{(3X}ulzd%p!(o6^h$gnHwnxXUbH4Q=bU zm69(_x;4B0+?@FX7h%J74H|m(_h*+y>hAqHwBZ1a(c_Si4sn;$(EQp!6L^v?uPVR@ zz)(MAKdBYE*OjImh90RW@=M>!CFD&TpL6$C(Wt$z+-4wKwpE6#8` zhiIJvLlo(wb&1IAtNwBaOp}ICCrtzrF)rQ|ITrTlK?SXLquc0y0F+P1{5t{wqDWeU zs!cYDT!fRlJs>K4vqsoY!m!qxa#1|)gb@(H7tmQ2E{6o641SRmR)352Ul@^?AL%pr zK?3!h4%D~DUeBZgkQNDMo1G9@-Xzs~s9Yz_sRW*%(|nM;!?hR-nn#CI94h)m{gF*7 zBEi+G?|q18Ngh;fjc;+vAQrlOz;G_^%~JoEqZTUcclc`!nB=TQxowWz@Y%6^Eu-am z&VuZnxmVSG)xgpKwlIDwyWaX(U(K{{sh|@==EWZWUKQE=pPL62wl)IZ<|090e>OUdMFYE$_VAPix_SJPnd z&M{x@3$GST8p(f|HM#C+#y&WLpY_6o6AS485gzZSTz)0dHtlim^EvV02ZEOIG1xN6 zId71^U43p;9^*+Ubq6QB<}ToV7sWZIJ)V6EbC-S3h&E|hcGgLO{vu$u`rwm}LxxA~ zdGK_!?@kS-_NN>k7UlryI}BAIhX>^Ka4?xYOc6-*wPMWT0UeP1!@&Wvf!Lx3-e*Uk z_O2@q6=uxCH&856`-~g<2q^x?ono5=06TGTsET-bfS-TYh+&m3LjR>$8)gArAvF)|60kR=K%Q2r z{fg8$P&E6Sz3sY!P38jE2$*ERvOfr`RPih3{G|IQ~)^2OY@AvO6H5fbz>~`7Q zwvFEDumH1ppO##HrWNyTM)BK-XcZU|G*GtCN;o-td8J^`5ts1FhNJ^u()WOpSTQj% z^e!*@jbg$M;`Jy)!Vatr#n0MvP%#Jcn_nneWOLoDmc>lx`4BX}!JPC#zsmDv3t&Y2 z`K8IxFeQ7ttypJZ8+lCnF0bM7*17AnV;boKlTAC6F?dc&kKeL(Gq{914M90{Fg-DG z%TJA3|KqZxEd~gZ-eCZF?v2`7YRka+Esixh{C)#NdM0LPEnfne#V{Sak!&yAI5eQj zjg#$31~pp%TR#NZ0b+um8`R3SoVFxg0pu3M&z2-q+1L$$uiLgtP*Kd4rhkHdO&i0VL-Pqj7UEL%>cWYW`9@Hz5;`z z${q|edCvw>bJBoTe@!sGW(IIwLLKeY!HG7%j^hv9zuLXD1DMl9Mrb7_dSQHw_GSWP zci0*xi4jNa%IVa$_78wO=QO0e;s}Joh&ERk!K)vG;e*9A0{l4~U=$w?$R0bq4hp$! zevS~s4A;Octj2W)b2e$@XrtBA1@hiNf`6w1b1CGnu?Cvwn)-^B@`+<1CzeUbapyqB zwEgmVVCa1I5rc@x(fL(v7JvxJ<-*5?OUpheK?DAyI0*zGK1_JdlYt{4G)sUi0H#PC z{GT2NI;?C|?fiQ3ma4hE^D^`n4vx-#5}*tFCum-AH(@1XTZ+xf6+2`+SRT-h&(C{q zomP#{_x1J7Gs`9yT^#||c~E82&m)Q}HPt6K$i(dfgbn>iR|7Fl4 z>59H!5IxIKlk{9nY)>frMgUKl@IC$>lUtxp5w8!-099K(?bC!%AT|IzQNiPP;)h<3 z4CA*E!;CnZL*G|$4)TcSL=)oT_+L3p610T7cz$yLtamM8uPIF%M3T6Rrw*7csTgE0)UMcv zB1sv9oTjWT$6R7=nm??83{q&3z{!ZbqJIEVod~E1c1H&x!1n3D`P)}PnVx5!Xcj;U zPY#j_>@}e(a1UVB$IBOMqp=bxz_Y0R@7~O5cnomidXKG=l(V5@oFFt+{W$Uo!FEPl zB$tG|-`@1lj}QO>U_wPI;&uZ<{4$#v^=thkOkxfSxuD>c+^spY@afjm)1xCx?}CyT z1_8aXr=|U*0{{zEdEaB&PpW=ye#lT_zuylb-{1oPg6U)7Bh33OAX_;MX+Aky;`BaP z!v(`mUkg7zY^BgPK)3yBYw%nlNLfEUEz1_lb|(ZzsksUN=Chf_sB9Jja0Jk375K#D zBy~fMz4xB}z(acU@I5fhWPuQpDY0>2RI5+h^Q-}l^7T|&4Ak)Kn>FjHOY0EALd^8vK}rf}!h8USLu^*vEeDt!7~ z7#s(T)Pe&eFEyO+LDh;n(;E0n9Y#B#h zJ4NXjwZqsp;>T{y@9pP3SA=RV*=Y+|v$KLWoSAf_nQ)JzY89`UK|lH$aDWX36a+_$e44k ze**v7BNE+AkWj;CU5p5btQ^*s2V3sS8rFH|~8S_;T@OH2&Hci`)*gijcoGJ&NXWAC{G`K5c2+zJ&+R}+d@i+xlK4>s~;-d+_ z1=pzkxu09`<{)XOx2;A&<-$Kh1YQF4K^*Zm9+2eZfD0rs_PR=^`%&pUZ|x{Sv$iQV=J zsqdRLi9u9ktKX{@$qreubBHxN@SjR#p?;W~w%Hj$qhtMZW*4`(ttyNbpN*qPP`w>^ zOttAPvJub*2mZ8j%sB(NW;=%py09(jupI}(N;9HSYbhZ|alu2ac^G97h8|D*c|TB~ zxO8^=@G}Ie=J}dk%YfxDX%KdozRCotf_&BEIWE#iil)8%&h(6IPE-GYyk1~EwiORJ z=q$)`T;7cRra|#57sxEf8`kO%Fx)Wr@|rs#p!n!#8;^0io_&p8O0~Ys%XuJ2ttEFk zneNT1P?Amek{F#U=|gx%W(ySLl4GNznzEb_;DC(G$&FFSQmqHoE3%s>CaY3@^^^+f z;NqB`_SHV`JO*pNl>^)4CRK%VUWyIw5jNy__4VpiC__cTjkq9oPFIXYEG=WB=ql*i zHi%5@K74Z5&F*P%1L%S{_BgMK39}KQ+tQD!<`hn4TImjw249XK3|(ReAq&d)F9_Rt zP2ac&m%LtJ?$BXpdE71>p}Zaa{ODCM*^jsKQZy99}+YTS*SB#@rBeTziqo3dBd#+TJ{UI zbm9vms{d_nqqf~T40no%0nVY6BQ%TZetNY%nOm^CADg;93^De#N`5Jxf*>Dn1&=k2 zoF*2>TtL=l``=gre%|#$K^t=x16!JVDmjwLb#nxYP^)|U)#9WztrR&z5)^roC5{)y z^2qQko$QzH? zX{!ZYOBERA{;OA$L1WrHPs9qDVvk}*@@5{Z#X$XmqtRkjNeKkm_6vYFf-gnSh-hh> z%d{{Nb`|tt6V#UTrRr>6G5<;l^>fE!hQ4n!wK>PF9s*d~Yfn-=eK@1>X15yZfYTBQ zyyt(er3XCd&B+CxtTkoGq9R%|WFIalo+9+lU!1OtKZnbqqf=Di!F~t;MKN6jsc~z@ z0HNxmrKI1yiTf48?m++#XV`ziTpI#*)&uB53G67~7-qr!@gb8;N%TcX8;yaa`?{8W zTSd*c>6wZw{N73RMJS2iC$(p4E^xWIXJX6!u}q5I4ZGD~whP(ObOh-ymp-G)1Y(Wq zno%SGgaN!!tvNnXwhrAltEp`KT2{dP@5mr!6JPoIxUPSj_o9q%WTO>0JmGoeb6 z1c%RSIZiNae}SzKl(Pjwv5E&L-qMmzQ2hlwg4+h63R3|Op@|OP^3>=7a1DoOS1Rz( z6lsLYu`kmt#kT$DmvaROTbIT(mG}KhZ;vo$5q4?27{2G zen<%C_hzC#U5*lTV-vlq+_8CryKn(;V9^;3{JSr}J2{k6XJ|ro@`fmYIVvVX?6cI( zJ}#){wH2Pf>4z-XG|3k>ohFfOfgthS`>sPfdlWpG(;+s1BT+4v#atgr!KsYl>;?OB z4Gr+TZv%Ve!q+AwVNHb4go5`Pn+CjU(#0W>71vB4cm0+UwVF^(}W8(Jb;bDO-#putVqEB=jy$;4iAi}^SWQ^=|rU1>X{RE0zGHmCH+?{H zl#bwEtA(9P4!AcDle*#`9Wiz&YaOY5LN6)S`vC8R05%2PVwFCStu-5?bzwHxs7{l|m+jK4i!4wLeak*=0uMeqr1}_DRmD0>kTnXsD|x)+ zH3k{2LiEfiSdJBVdFqM$m17bh$C`&TT2@U#uO^d4Bu-xX{phO6Qhte%HxPM>B0G!Yz>0qQ(?T7whuUsSu0H0eM8|rhYH6RN95h3uZb0OnisBnOL zcFz)1xI64yO!KS#fP6o-WX!s&r|z=E1voS=G6ZW02Nnv?CRFD`)pVU>c1M9AfV$ag z6P-!#2e#}5E=rYG)^ZE%W~=kDyI!IRhOOS}wY#H1_eq}WyE89rE$~r>jl&Ao-%q@c zTRVew2&FzGLQznhOY0&*883u{zr+;Kd7Z1ta`4pR%Sv3X=rDW*kZ#Y+3s{OU<|zT7 zOrN17Mh@z3L{lL?S{xzLNMcxie*R7^iXB~OXK>5ttN!YjFBr~mfO6eKj$gN|v)2U; zHbus_s#ART1*AeZl8erYiJMlWe}_^D(b`pSPy_OwRPdFR*$@NlrA|Kv@REw%7q01W z?ru>sY#~$HR6v}Oh3uhPu~7*?aI9=keBC+k>Pow?{`Tu?5TuXhtB33PWxF z`af8E52&WH?r#{!aU4WNMMRV`h!CZS0*avo$A%Px^bRT|0wO}_gyIMyO{5bEM5Tn# zC3IlJ z!zav=Gv6<_X9(Nn#0cTEYemnbC_ny=GSpa!1>^hU&ks7PLNHp&7ahB$E zI=H@3Tg5^0G*QMmPQu%j9g55B7@b|Hd;txg6HOqQZ*p4&@J}m)Q~*z0*p1V`Z<4_E zwJ-273yW3d5cme{;t`|Nqh)|b7gXwX7C|Y!O-JuQe?QdI@{T6~haCtq` zD7;-JBu>^*pJBQLAhJAZ^Vv@-gu~YuDEk!(_M)?sQ>v}Qp7Rs= z+Ek9`+m&3a7ljiR_t=EsKfY9>yj!^N z7h?^+WZTSvLGT(|$btW^T9%rr1m&36aYkW-hv@6n}h_RLZAm!xW&l$L}jN; zDhZpaSZ-|aZgd-ELX_SG0ZZ1inhZx81z!lC<7MS~wctL~)Q#R=nGDVpTsBAdTLocp z^6(A4E$IUdYO;FxW`};DZ;)DSg>=ZPZQcA|Uw7CTFTa<%Y2z~g$<*4hFSBp?waXOs z_{!5nh5)?dhf1^{$d*AfXy-w~{pG3J=``H>it<6oe0MY*tOH?342^_lWWo2)H;}sj z{NexOwG!~?fsz?IN=$aGZmJr;0EYFZt7*nXmwfi_pIg~m&Md#75F*bhKf2q1^_f`I z+u&cxBJW$mHQM$=J55kxeJB@Wd_&)>!mi$RkOWKPm5{Y`v106OOIPM`;2STB$FG zE*FAEDns1>$H@EUah>wZx8J>nI^vNhd7IWl3oBGSy(U;M)8)?EmR~lUiHG{JjD{ij zKj}Bn89Sfab?vg;uG_|^+gEl!W1cFQM9OGLP48?0YQvf@;4G4jn>7tTN;t;ToA=s0?4-fZv!%c|R#&957eW@$`$_ z-I&4rQR;`2CAFv6et90W{~K3pN2F|3&c#};?;5(PX?-o8C^N^ z@1YEPAlz{e#}iyq+xiN%!0U@?A1Ce|lbk%AA%EAhS(W6>tt0sF-;0!euqTG+Zg?|D z+=8bd=BF>f9j8S5DZ2rR_^Uq0J$vz@!GC?rE}#M#vbi4pm6odA#h`!vA9HjgwYl)T}w{b8&uBo z(Io4A3A6&FrO=Fs_G_Amy=Y5gvn#lNd}L8VICxm1y)ZD*->z* z_2T___Yr+?slF-1^1P^TM}u!Mo(dt&&>r-HPiUo+2Pq!Y_iKj& zgj0cR&I40EEN`(O6t}!bcB$bagKs;w$36j1VizBJuMz3QQ?@o5JRJ#;uj(b)?1isD z@8=i2!#h=dr&vP{*%H`1Wid%9Qq>z#bw}%uH=(9It7NtN-=&|0M1Ig5s^j1mqN3TD)~^<+VV~0@n#mUrJ9rjAv|tPW19_4K&nUa50}}XS>c^qq3nnufGthm zjwOtoC;c7;zPb>dxStVG7+*mN*^X0V+_%FPNB~;_35tb~Zg2f&M^mF5UWcf<;{Qf$%Fn zQ>7Z+zn&duy~W#vJ)TVDx)#20&ml~=NX;Um=&#$SYJNM#{6~yPg~XG^$`2M#O6L)= z{j#oi+Sl7O+Ks-n8)Zo$&JSBSJ8C&PJIYVZd6cmNS}SPNaE-ZA`7bO)+-9`Nx?ADQ z^oQ^;Q6CxA$o*96J%0RZWwhYt%1UgspHn=6$NjGTs{M=gDj5EmyXR1zR13GuOp`LT zX5|u{3*iUZEO=y4A5BGzlf7)F=j2{q`3Dn{2+XYIjXNs1n=3)SIcGd>by-l~+z36g zXfw`Two1-p+aswTH*1QwvakF>=l-)dgodY3(aXU9Ffn1sF&<>F-xCb-_y^*CG3%`Y--Nt4B5B(QlycM$g$Lj zdCc-~Ye1cnIr4JNV_Jj9qY^JoV!vM7J5>*lq3@{wZfC_0% zG0haea%4EaH0MVskrZY z-jNOd&6f^JIwNgKsJ!8>R--t_>lrUfTY3r8)xq!Mka9zSmk6MJOkdHHt}Go zZ>y7}Mr{3c!i5X+!3O6{W`z1B+Lh?3@$<)pmx7x8PA1))cc&W2$7M70US%GQHl#;pYM z6V5)YHq1%036bkBA10IHpZ_A@TNtFig~mC_!PCjQJmI!Vtxh}|HOkkc#m^4;Z%Uc$ zW?LfVz{X_LYg~;r8ZAfh%H* z>k>3M-6*xr=bL21YRh%fg$X{O#G1S_hb-8;u8&FPQB?gBMW4?h2*X`6lG9l8;eYXH zKY}o)f?vTTH5_}}`rx~*tmABF+eOm-q}x{b6P+)|Kk*Sh;U!maVWwiXzkj(*58UC1 zH~4U=pO&jHQ1at6(V=ny*s^qpZ>BvO{$w#ZORQ)B}qO7b=O)$d>t3av_Ec+ln!He7` z2xo_D=n*lg1w@fpolm(?p=69zLohUiBb(>BsL`wUxtIgvzBRMvir!(L1fk~ld5T$jbl zX`K^i3wr9SS8(4Vl%y}wI#p>qdw^^N=u+DsxkhA}&1qK*vhQJp#7valULM+uQkT)B zfZtw?C`yZ&mvt>QeX%f@2|HHN)@U(01OJ?R9nL1~Bwmw{^U5{% z9Leb~xy45#*H~uYmK+KBG$Fa)!S1L~S%D%<0}zD?(ukm1nq~tMa*CWqc0=n4^JLPv;^;h_h^x=iL^!t3-ZI{mG!f~? zP3CgEObuUW-i$rADAHh_)cX)jk2X2{bYDz(iK}=Gu_A2Y^8nsI3lhywhl|J5bexOx zKo$pSQm-dA98Dy$eXv+K6<_!&yI^c^l)B%?pyeN2JzSBZRd~&OpqSg;gH~0gQGL`Y zJx3z^$4{#VL4iQQo{4K?mkf($pIgNR45Snol2zY~CwtF+^ti?1KF*dU&Fk*sFRYz0 zy!PvTAec}_u+@!Oo~7?1o7WHo^*=NUr!|U)HHMHiY`tf45KF#dNd_!38hQp+YPFur zUllz%bT@u|MyP)~F))r1e&5{*OE&_M=IDz|bsh=qe8kM@j3^FUbH~a#?T=(y*>qBa z!}*`V@x}9>VGVrP`U&DXLgBj4Pn9}Vxno99G-3P%T?53ea2@;y3Jgqm{!>7Eei|m@ zr=eId?E=LNuEYP23o?}MznA~1OpIl;W4;IvKqdyQRW%Q%$ZhHkX&)ximW*8^w+Y?f zO8b3st#;Gwo6xC9*|{c^g^}c=F9>LTaFaJ>td}M$hadyQqiprsHJ!tXq@_8N^yx4t z{6de#OVlqej_FZ0nk4Xa=gqNANpJR0#mYU@BAR?`ky-Hd(XH#WC(-9jie7a;8R(|V zCh?yN$Do&*n??rv=q%d?G!1W@fjduqkq;elc0y!@zIfh%^TKSf&UOaONN!V`-bWj* z{WH{dvWy(M^Yk87YLhdE(p-miDNYj>8@Bcs>)+zeU`(_PE9nRp^ z-MM3Ljlvr9dCTo3KIx13|H z%irEPC;YkXsX{L{fTybV2Xi=!!A}Amgd~Yjc!meNm^nb?&ir}d6I#cQr}GEslX(+l z|DWIT5yU;)*!6t2GtWAGhpR|<33|8*7zXsHWiCz&AZ>jw)p!}N4_Khc(6`fY@g^W3 z+)Dnh_fE_35e&=h+v$h@lj<8CIUn%8Nu%>+N@L>EZ0{$Y{>kJ-R++8 zF&qn6n_uo4JMs$^+OgA7GHOAYb-%6z(fj>7&ar04)WHp*?M_z_pTpiSP0H8~hHtF} zw3MKNT`DLT+@DX&G!)k<-VFrf+0kd3m?pFv4B5pl$uZr8?890 zbu%&}BU~8kS+^DMU)-Xu9X1NR(b8Ay?4^}wweu)5X+B$buTyy?WT^?}gP|Rvvd7fS^{us#MKm4~pve%y~ z4-~wwuun@t>X zL-CGIPUOt#ZjW$iOd9hdD1&Xbji^3?K!q6;umW8g$22?$L<6pDZy3n@u3x79$n!y* zK$a$Xd#``u`NdJa(*ju!tN-&&ix42EwY@KDfEmlsSm0U_3W-{fnamFE*g0^@p_P5W z@IuYu)msS-U^wvH0!5Cie~F=^iqcPR``lBQ7q<|=Q&AdmfYr*n9Ra^QHd`Dvup9mu zi1ja)TqngMKTVE|MCn^%h|y9(I?Eo_-D5{Id>3n{Yutu)w|4KRj`DY z?JBUx;DPJF3a0wsm#=*pg5=`9+s%&xOzL`1)QF0%|CXx>-hF@TOF>}ib}q_N`G^;w zW0jq1Gy>fdzWr;nVPK{XK!>zVE(k|3c6rynVw|yF&|vb8g1ew6H?;lDGYQ6WHc#fp8^2+hF5yHSd-c7sCa3d6eUrEj> z^>B;nG=?r0NAaW5D|%f#25J~jJJi(;f8WDi4;f5$g2U+#Cuas{pZXokdC0iqOO_Q5I8wWA9`kA2wxfJ1kA6$kP1{H3zB2AymDrB3U> z-@RFo9tB*h5IkW2#CTvDh(Zd__N#0 zFzuV`<_ zHSg&ig1o6h(7h~_Dus|La-EAkkV{7|;F>cIuQoDSx@x!&Qqh~2wf9`6EG)qNoL`)q zH0}Wc{H>x84#w;=diMf*a%G3;3cB}t-*QYkk;1&Y0O)E>Hj{dOKC;aHhjbbv%pvwp zD{{V~Ku()X2Dt|lsjDB6@ty-(VVMi0e=jJ&x+-+puP{rSLY94(IpHd7?^kpk7gONK z;H1DSUr3cO2PJFJmRI@4@JH)X{)r8^}I-MGD9^R1{KKu;X@5 z>YVdjXF#m` zY6Q#9zVyJp3f=vi4u{esfpzOO{M?2}EzL~Opme%&u6A?enyKz#|9aID@ezgxfwn2~ zf#&l;XS90(+^d9GNy8t!r-(q*Qe+{9RnW|v5U_{xbKe8d*AwG8j9rXbe$pkOf+x)t z4P1Q09;&U82~;`Gkr8*HT?@~{@6}oK37uLnTn!iAO1L2YGjy1tVM7`w^H3xON(&@c zaegm>$@>OX_!)(>j6$c!l{zdTTpbFVP^_xaC1>RI5`tA{!|}#ma~ZY-*!i`A$EH~@ zQLe_{OmgN$*1Ln9Z?S{02$nx|naTU`hR86wgG?(~%$OUS6m`8`UWTAeig_*iip9q* z2;t%AWY|;9CHOrlNP|JFkUYrb-9<&$453@zVU8ZgAPo}4S8W!<1(tDex&44Xp!LA( zFl9?)$ZmApdC#mVDrM^X44mE^FTL=vZ#LG}V-+lLY;$bYYfaltd^M*0QoCTa2b9$U zqCSD++1h@T?uU5vXcM;Hczu}AnULV}!+=J|skA(UYe=~-Mau`m=GwD7%;5+E`X2lC zqTnC~wCD*su8W!8MnvH^zKFF{hE03XaYSZR@<-1#@TgT8EXl&%SLY>Q0I>LqVQ{v9 z8-XHuAiw*pjT#KZYetHA8J0UCV2)?8XOYB3z2&t$2i{8INaV)&`H27uXAuSR;tWaL zwP#}DF92&6FXM=r{O7uIb2IC#Y3P>9*x90o>vUZ9j6-x~c)sY~LG;ZDG)Uc-XN66^ z^dr{imt!Caq-QlT>&!mpW(y^DcVmlA{Qz$K>ssAu>Q$w&X}I+;`aW#fA#b8>|9nB; zqW&uGvSNnaDQHf)m!^3v&Q=DZCze4^S5HSreSMVe7sUAips(3C1!0CcAT*!I?DyDw z#oircR%1R&YHX8IDXe(b_;7TI`iBA7w-E-J&ZFozt-3kM@%gHX;Jq36f^n??8?lA1 z9j6m7v;>b7D9~@79)tuAY&cHF>y7xC>5OI?)A2HJ76!rn2M1MrGC;JFRwvGOu7o<< zTLdB?747!J$52e%KTzuStJBVpPOPD%`V|9j3Tiy53}(-2`MYSoct%@Dgyf_p;!8>Fj?7$r^y?_YJt>^v0~HkO44J~ zQQ5YE8{vNQ?>??sd5{zTLXCHR0;Pe+ZQ!Y%iJ*a7RQKZtR2}NSMg6B_2E;Ty7Cf8Z zyM?5B;Zi4=7+gbkG4gnIZCIpsLsDn3v-KMZN0Mcp3NO2uh6mETLyP`)jvIqC8fs&f z`J@{IOn@qoc{wV8LX;n-IWM;KBuXzlwd&g(IZ6-(#Z0+#r99mVM5g^3qacsouj9Gi z46+tZ%}R5)jbXMcSRWXxWiHpdjng(68s9i)`6nVStEJq5I6)SWUQmje_G-;<@kn1o zG}3%%0W#W%iPT66v-1lDovWTt+2LrQ_OUBRP#C1YUTRlHp|7mXz}nMUI5iNA4|$fI zlf)e06a+pn21=lO+No&ZeLwO|r{4gl`s`h&qBX@oGT$LK$Eds|{^@shq-COphRcpB z{zr3k{xcjlg%*-=8gC;BX!tdFAior}(F&915>HqgslzoacOB)qm>1%(@^U`-#D#*^ z$;+RRu}Muw{wjThiBFV?LUdv!P;RMBXJ_D%dO89cDN2(#q=t|sN#iiThU%?8i`>V- z8|M*b_CeUFHj@5`q;%%IM9%P@a_MCps1r^4O55^#(C>Uuo51M78Mv!m^;I$o_o9Il zeJ}zQ+*T^50cTc{OYSf%X52?MZNxU=s^XL(;)VeCMO1`x)=7Lhn_B6BvMc{!JO*j5 zwon5o0RRo@0y9FvwpYUa71unYK*_T#)dB4P!`s=SPE+-@g0(lqmMWMfs!_tWzo^ z5Eh($d+Hv$0U!!ndPf;pTKiO8eO1>ytYJ?iQ&Og}MzN`RH0)S+=yBjXECY%VeEA^PiieflMn_$l2>cNEB8X3Y5Gl@Ms z+}iKs+eZo!{Zo!ZXrw`G@sU>h2DlOiS#3Iea%gxeDylozgI)cCt~{K3SY_p9*dt1$ zc^?byL*7cFNHdMAA1)2DApeEo#w^T2$B*40FTjR3aAkztSmx?35v;e)a9GCi0Y@5` zn5e`T`3H8Du;)1UtJ-Apn@mHuFUxD_j=_53(oLR!D2j3_HJ$*Cp8qCYvTugE&=apo zKKclr(J9pTq)p`*LRq@};a>hKVRfXU29~F`o+&n>1hDFJA9u+zL!Ap_v_18IYVmDm9-qnvc=q@ zlRrAE75#SNH3hrY{~+&q`&}r#`{X7F+*{NbNWp-SpWy~^d`w%brHd7ndLU-x%-~)5 zpjR^AwWJ?sLTe!iO~jOthE(+hS2^nM&-{EML_X)8!E1<5q<*F~>A6KXoz8s7*MObv zltLtyz@6sdBU5W&$oH~@^N6*6^MDR*v>ySYc@xNUw-!4KYVk?77KLUZzvo91dhg0> zlzd*Q;Xt?x8%?J6f05Gnee@_5fXgNyiEqzNp&Q&EMB|DBd=vp9KY?!G&2dG*JQdR2 zi^xTD9Dj(XfCwm}F#6CIFNlVGWk?Hi^!kE2h^Oa0kouObSRyG``oUYh;@9UC-M+Zc z*kV4PAX*Ze_yQKxMtlVTS{xadMS(Z0;&Pc)?@3UDe29f22ow)K+}H;Af2##O&&eVV zsCeLrgv*TYzh}dN*jsS~L+TNubNu{bc&Wv~2$C+j}k8$11-`j*2f zr)rG_QhlURgq{5V9o z-z-0u_LQPX`$uc>Zx6D?GH!lQeuMw4M%z{0V~`8oz;dy1`SmqWvx> zY3=vqMk8N81s1i;qsJ!E>ZIuS7QS@bYMMwN?ISR{R|3KSA~;7~P3s#^2gl$6u{wCt zRTEJ_>wZ3JAe79Gre|WyHx)}uP9KaC{^7+kw=VA~oB)i@#kIIT+#$II$5wl61YKzz zO)h@b)(b4};E1BHmO6%f1cQta0^mo+rqNwX60TCZ|0$GuGn zRvJ2L6x~9;G^SH8PGItZ37u^Np6dOY9y8{k_XdWnB$)@ohIp<|)^5n&WL@wC@zWU- zDG?0-Rux`2q7e!F^i&>b-1OId88oLvHUdv@A#kI9^#b(B1Kt&zvdx)O`Z9U9lx4$qLEWCa_ChO z#3sLe;o9g9p){rDR&^K9rTFnf;xK=3vEYwAZR1+Eq>SaA5GXAK>{t_oEdT_y-b?13 zUannzsUV0rpe6wYtN^gB$Dp_9tfr^)0O@yU42e7F*@#am3s}*FG6EScch}(Cmp6%* zuwLy`H|RLG8TABU&c3q}FP#p(D$YNFC+Xu!m6Aen0$F=Ni2pX!nLN0K*!V+Wxr%6T z%m80vlK8@@;9QN{{`a0Es7+q5EQtQzOV@n``Eb+oe3p(Hg{5fIaj<~WXSMn_Nm*B^ zoVUO@cf1z@m5U%;9}_{JIu4X5WDr;8WfK6{6FdKmt1?6tfx3)F$X1o?C_jI$`{nquCEpCoo?>U8dEA^(LI#y<}r+|zSH1?Ii_q%o| z*U*AMmg)2KM4jv&p#PO#R+Hax7au~n&3Jv*N&~Jao=+SjGXb4-ptvS=4b1~@7G3#2?7^f`E$AO8YXITo7%*PzBWq5ut-v* zES-M@eRC3hqSMB(M{|3<{=Qx*3kFV<$qE6OmaySR)+*5t^AUc+`+o=zt?##!HBN!J zhDr+O`);$Y*vi(`O%iROwS}bEMGMW%*!z8vGz^oi6 zqfj~yBxAXg_tmV;I>G#RhY@D>+j*^H8q8JWZF?f2@L=ru=;RWg=}94LWk-Wat0xG; zHB;QxEG<_)Q0fs3_~S+*z5x?c$v>eO&%^6yGA6aOSjCYRbQ-%zqVDyclZf|W^;}*S zLsti@RCfLjq`&`Cc(*G1)C{N{4@i-__Z3bB7xeh$HrhQr+L}6U!RL{x6ZtsN@!i}w zc$w%U!-*mNdjJSHfie=MT0;p+*8q0ooBWkvwrBSAT}Qn`51rdX{U^Ier~z|Q5o{KO zA(X_*+CZ^K1;{7F@TTTze`9fL;}uLdl?yMYry9aGC!&E1xNi2textHeVU^Gyq^4Jy z3-SEE7b@q>?s{rm0w($r6FL+}XT;L`n^~vSFL#fBRCoK0mCj1^@T!`H zgFk=EuOVR;31{jEeLVK*2$tdxg8fyCy_uLPnLn~miPwX*G>g5K`q%YPcimSd0aZpA za;pA?TlK#iGaawnBkT2U5DmIGP})~+khxyZUZs1uz7eOkPL$H<=(6@b0&XewG*hy; zD16}ME(bxwD^c3)@=XGn%ecyS^*%afv$G0b3mQXup`RC<>QzavK7j+n)YIVJi5sy% zG8Md7fT_~7v?JHneCt@mWO+S(OaNMON<7Rb1YnsDDM`T(-kSIPp$mONX&Pg9ouex#fGUSw|mG4Oi=QCXy;%IOQ zK+n!ScV9PP2B`<7+gox`x(lEhg^^12D|ibmRSV+zw>*9ImWSVgfc7Fmu; z09!(!c83+kgu_pT2^t;}j}Cl%0kj)%F#!B|mc-N}o{H6er|BtR0+L?FrFaW-CgD?- zvus&F-(k0pM|0wS`wK1Yl{EtgaL$j^M>QCUL08WkA`ws5JBCgPh3cxpDS+IITuHZebQ4K6!{*`nfRb zl(${fh=`5rb)eO|ezqVn$h~Q3w5|Mr4{yaSfTNx~_h*8BG{9?j5J^1g1%e>XJON

1Uy#r(3yX_6x<~XNExmxV$V}2l6QpsD$uyb29E@lOD6*9%Csy@#i=Xt(yg3Le#5z zx~(@Cl*PqYOnX%Ym&WHl7Gc5Ew~*#Ran7d&c7e+9c=4^XV0hvg1Kxo8{#qk>wsES? zw)Olg0B>~mqLaihGvCv7=uKD&InKml3iJD|$s9aC)KmfO70}0#MZmZl6%K!(Rf}y2q*=IwbM9_{|8C8!;7Y$c@;aZ-mStQlj}~O>zA|)>npOH#(!~v ziJri!?Aa%!U81xXN;C|J*-brK@7B)ZYK%Jz!1?wu>mI8PEfk(@($HiIfeU|ZN)`G+ zC2N?(O;2ZsUS7?*F8XYhF!AE{K1yXUcJ7WB$8DaL+9PvYN(Z>|M+Otf%s06LMx;Ti zC@R*;SxE7(>RM?Tjx>JHt%5YyHG%~Vn${}`L+iiK`vi0)S3fx#u^7qBbP5XdWNFNyL1Um3odC;YeJM$G( zfdGr|=%GpKztHsx%kMZlzn>oJsDwMC$%x{#BXMrvbbGm_!5Bi@6A#i{bTzjy-m$#_ zpk1{I!hGc)0&qpEjriLh{t^hnM-i>>+I?5!^KCtW_Hwo{nbd>>bpuUT4(IZrwIHED z{kEq-tAV)(T4|T$ihW?+SSVlL3#O5ezECeHQ1zo~B^!dFG}yr>DAD_oFG3sL%M-)+ zklso*HD*U{-?)4fN|+EdpS(8qL~%k08SaYL=za$*P!ubzIf))GOG4C&#=+WkC&C)A zN-VFZQ-~gkt$vBNZPNo|-3K>~&W^m|(ihpls$`^ceOcOE&Y0)3kx>RyAmn{)Wg(TZ zW+;O1qdnQ777x<=GlPSU+JYPN1y^)yXqryxW*u5@D8!O|_ZqP+2@S-UylzeM z$IXMAp`Y)}JhJOBC^YYgPlO45SH;{K71gxU_K45{YEQn82Jy40YgfesENX|Ah)u1T z(f$qnO)db+8qqcCz^lvj%hklK&V3KSMVUp2P`LN@Sb}5lza@4CQ^Fl;TWHegQ5Drl zxBx?G%=T&3$F*823D`IZ-8UO&_U{ckmid{t#!uzNh1M`P?KIrY+DOlvQ6*nFfc@r* z-Ydn7r2Z}Jtp`Db@^=_>4ER=sEnxLt)y7eAx|X~yK78!|6cjWJTsYZl--Y-4t}s(; z7atHzpx}l>*iS5e050tIdjJ0NcM|bdzQAJ_(PBrQU9gp84;DCNS${o^em0Vv%P4M4 zzDA^lk%}dOiWFe12ae#`ghP8W@8hFt+f4qMzbJ(9=#665YDn1^c~{n**JS@J74_}P3EJ61mFKK-Jd@pZ8&*;U( z&^n};xp_q43!(&E!bfnT=VsXjz;jMp@6IsuWEgI_8ls@J$OjF$l zxGMru`oB4`yI((T+4l6Z)zp&%qzji?I7cyQ|7Q@NAYgRQM$syy-#!I5>SWF`oH5}V zXnor*4zQWha32=0o%`-1+rDX*dUWtET%JfUYfv|WK;DBy5rz27j}fW})kJ=TmS~Y`;!d@Oj*BYD!%K{tN4?*d42hFU^km+?O`?;E0Xr7|uGc@nh zpPgK*!D9cc+}Jf;$nv|NMEf62_DAiqd2cpzFA8yA?u6=5yvC?zn}WF(ait{w@o!bv zt|~=+(~qE>#X7csLywBcDajns$v-rrLZ3LvtKQEgvx1v-MnG$}(qu97h0|jEAi=?A zVd%X6buQ`~Rg96OY50iTNg17Iezv&BawUcCXZM>$y>u?yd^)|m5VHhY_Mo$#QiZ>x zGl*`v;9jJ9i}zw0*D0l-M^D#PW^N9gG+F+h;ZT(3<~;C#y|{=-20-RvLO^l}gEE=*VHyxBT7^ELmn-g6G4b!xFN1_^X&ymd^mE?xQeGZ z`HxkcgG_MyMWU?Y6qmK;sBKJN2TikQRnrH|#UxU+x}5x>90wP#?br0Zf`uZ#X~OGy z_q6b-@T+laV#PJ(%8;gcUs%Q2W7#H;)tqh2sv(|krNX{b0iw|BIdh=le+OKGl8AI) zO1*0SO03tMDb(OB+IZTSY{+m5#^&VeFUrDFa6YQ@a@&{QZg?+!_0b&!j68qVWB?V_ ztZN?_`(&OnmR+II^NL^-tw7VQT zM}s1jjSfl3(z^uA4qRpt)OK>=3om~*gg&7o_KGAtd%U9{AX0P$cHU@GNLE(=xqVXh zV=&2CIv;WHo`*0ag&VbupW6t@I$0cWOF(Dy8~(wYEst{1&hmjdJRFRNsEW3NY=)(~ zfC@_AVvCIp*uresW!=o&P0=POLR_Q;r^Y715gjpQxKe76-3@R~{W8vxJJ40P<;Y^nlYA2g$y(oDfr zU*1}CIsF0<3vi7My`z#1xHowwGGGh@ZCf64|IHIH!99&oHNU0bsdhFJi$ds(3nVk3 z4(m-Eu{893dx1y?t<9M@bDE&qxu|t(0KQPgnA>Gk%Z%azjOCeS8ktTc$#db^R+E}c zIKz~@15WxE^Z&@{bvn^0!T^3WV{%`SwDq*C;-e~A=HZsMc>m*;Z5J)YUTbGvEuL9< z$C&TjX+eKQYctxJx(SxrU_96I%MEj*H*oH&NiufQ%c5RySA@p5P_f6~M=oBXt`U07 zHnhq)M$qHc%E65G1?5W5-w(!nz{C^7#I{B-mvO)^cKHgnGP!DsqrgDm|8F!2O8psw z8vq^wnTZFo#^`sDFdsx+OjD!dzOfaH9*pF;&K`V6ukozOEe-6`Rz|v3@K4m*${6v$ z^HIK1JF<=$AA)d-ctSwYe6kDF8hES=I~n6f(-Y%l5Wh2Jia>!dYJ!9EjCb`A{Nhll z*2|NREfePCSHliEfPVIL$=J)ya0NeVl-nC+e@Gp<9kek44y1ctLaTS+bW25*{y#-) zX>B^1lyWU00jULv^KfNL0o9FL47Fj*1TgZxv{^Wv3~%IoIt|An>%Mfvoa=t*aZu-Y zk50`h=b%f;R%1~KcCD*-B|I6HO+o>6C-SNdozof(jVwRJV0=&qt)##!Bd4l-V(6$_Mgz-sMaf40&})0ntg(D!_-O!bTdf(J_XR^M zWqTU@N{s2L;@EY~86K16!S2UHxD4;rewQ?8{=N3*g^bik$65$(TFeUi95PTvNUh03 zWU@a4I&pIl4QA%^38JjcG@tdexxCwY2-Og)I1t$_0?;>wcT@*~igIM;;_lOZt;VR~ zAgzKN8mZJnp9ZP{0IdR(wj4nlZ;lr2IheLBDoE#$X&{_lo-3i6)Pk-YG$F@ObqsPG zUA9c$?9QI(#AC8kkac#Xi3xP2-o7Pfy;~zkw)6^$Y;z6TGBT)I5%kqc+f_Xn4LAW) zXja50uxg*w|8u_1_Q4Asga;km-A(4K7>|CTm&^rvs()&Ao!Qy zbmZsFag)uWH)+oknWKH1Ztxqb1M*S3G05eq&T`jt$J!nGM?ZfEc2H>sv5&zQC~wPC zr`tc{v0gbayV)-0G3gv^eB<=(LXq@Twi6H$t+Yg;Q61h=DS|Tg&#jUh(g`q;lQIxx zhO7e(A92EirIv#IcW;=5J^s7S@LXjzgx6oHp(Sc0c}_3Jvb@{3Ed@q}%h&v}c8>dV zQTZV-k?boDJ9JJE{FE=i^EA%nCx&i zt1S9Ui71)mttyirL!vu3o^pksV2 zR4r+GFuO@u2x4I^&F7<4@Hew!$E&00KPJ#EI;o*GSZ8Qs%cr6akx^8-KWXy>7I%da z4w)W$Q;LcTZ0*v*KnD%6iz)6;j+aU7kj%*99!R$#GqUEr!Jrt;FVpaAbMQ#|9qKos zC3)#WHMkCTH!CH!0Vn3U@vuvO#D?vXF0tQIHhiq!pOgjwZQ6l?L{;wiEfr!q`4uf5 z2~%Fydw;Y3sQ9ic@d74Dup^Wu0v7bj)aZJVDRaoHaW)XkrRAppt8&F*B@NiKju7Fw zS>$w^;_hSMi^m+4Fk!=-iQ+S@M^^MV!W;HE|s`~a8gO3vB!ne2# zPHOOB$1Iudpag9%;+IeSZlU9*ZiH zgacgxZnYP@v2_-|ob@q8D-?%iZOzV#6LaX`1k6Rz?7NJlOdsK~5{} zzzm;rd)F{W|D$y~8yr%?wXfjXOno-LeFEdRoSK`sZ_+*SwA_3`iM-R$+eHm|ZtfGa zDhtRRH!utanW;hbE@750JnWWa$dr^Lhz;wR_Ymy9G6x?kx7c_7?U|TVk7XRlU0ko% zW+B{c<8!dYGV^f)e_3>K-1t0qfz%eRSQBxA*TxF`DfXP=R;R|+s4CE;uF)L3ceV!bALy_K=^g?Ww<+FO1Lmja z;8ozg}_MY--HD?{U5(vZ&*+( z9S6GLdlro|@js>=W^C^8_3@-RD0S?d>H-1)3qto`$ZH7L0*_;CC}ItAen>p&*gCpp z1(zQfNyF!YGhSpZm&G7uM$`b#@Ru7wQ`4|)9E_<6mp)cLRxw^r^O2*Xix((*5#Rn4 z`&-s8{I`rS?Rr;mA`D8AfJ%ZqhJk^CZ$P1r#EC~V|!H6)1TnGF~L6?WXLE2nYLLV)67Jyqac#ZO^i2>P8y~s9NU($k_ zKx=w(*<&os>V3D8>-KRch-Q$AG8|TmW4d7GU!oz{cIKi_w2v2-!Oc2lG)vks0C>@w zBsk8-KUqGJBr{;8F~-tKJ+qGj0~-fr@4p`6f1XX0ZSQh$H4jK6JA!dwrqJ)pD0<)R zTRneEx0Xwn=e{(sSPF?5_D}h8q-gmg&8aS1P7@p_V+_}FhC`_NMmhzmdA8J; z!KbD$){z@W!K35uYh3XaLO$PN)HM8O&*bSv)qTn<|BW`Y8Wh_!s2k@ZkX2NRb_Yww`G5I`PrzjH9nW z^-yJrX$hWzk9q71t`*r6p}iV$w8e)IkDFe@q`95Mg-Nhc%(`4gcaFb;Nkz~h@B&8+ z?umE@bm`H3WWc`kiYSUKmJRDS6DY)>fw|tGa8f1tqp0&7+)g7{>*mQJ^tjml4cAr; z%>rZMIP>N!HEF7zAQ%C+^?XAw9<)wxQ4IO^?du=g?8Y4)1*66)2fg=Gj~qUC6c8_= z4}7v&1S?hsyDMTGlto6+mRONo;e{DgrH69LZHClO8tM@csW9EE#xL(mFFnqDT zFmmud6v6|Zti9^9s$-n@*n2GPm>yLq;A~_Xvj#rnQZZAjM_Fp6u$$fVV^3o4~mpWKf-Mjc@Vps>1iqiG~q&rOV_Oz z#zP+~e^K*se|AzBjY-VVNNv(@z)hEMr>cCGo{<++G%r!2+7E+qIreuFSiyYoC)u}+ z8b@~@Js$Pjx0*090-%xq)JZl#I-@CszPa0sDUO-rB{(Sqe)XT?YZ+%Qh>j9k>le-n zs7q0IvC|zrHOjb|aT)Lxr_HP<%sdkp`{wYao)co5>)=(-U|^b=ck}V#Iun6Pb2CfO zc7vANxg+u2fmtc%0m*pw(8p(w-!g?52pX>2sV+F$vPWFu`lyaH^*+P#Z6B-yzt^MJ zeFJC0Y@uFSrTIO&j{U#x#31S7BkuB>zMub{aQ>%2orZhBa6Wo8MrsRcVkot>%7O&; zAL?$#gX|TXR3B_`BQd_|)M%q#9wZ9Jkv>LgR~HVK->$>9Zrcr=rrmzPbI6f_Gy~eq z_AQKV5aj ze~ZCD#$@)^wY7y1RtBZEJB8=gWHaM2V11}q*k1SKC^~a}&Wq~9@DSVb-B}U3pAk2< z%L|4|FnIs3lKE$@4Q+0F#hvFv9QbeYpf1|hr8{RG87yF2#vtQAOlMq490uo2qEg*>j(k2Gc2N9kSL&32^@PIt^QyvfJz-i>NjnR>{OI6{| z2#llGK*wrJHk!d7S*L$qD2RjXW9J!=^fb`m1T9-NW+~1(t;garGxRcq!sdEC#u;pI zZ^GJ-FH6F-VNllQ&vjIqHYVLklgUzR2-!MczQwFMFsnYbK4zR$DA1>VK_W5?jN?X^ zH_z|?*sTTaGftoV5pzN9st<~>LB?Z2)wR$HHoCPXKovtoU}q9(0iz(YOB}EP`+K=q zL0ra`6}W;^uKL*UESmqNv$Chn+WGi4}$l$nOe4F3ec*4@?_kbqa z!)d#n=msdlInKksq);qY@YQR#ORX)sBXd1&d-VndnnB0FSIRBa^^CT;iULG!F6{NX zP&5;WmzPo1+49K$QT|vkCqEk*rl)3kAKrWCW)>hkCuD3BZ-@Dfp*kGE=EK(B zcw0S;r1@02X9*dO&%h-)Z*M}y_J}^e4OavV7p}*CTaJ#KcDuL|6;a}A@b$^oLGEov z1040Z1@i6bG1FM^=B9!Kq$t~#j*?%3mp1Ev6cXK2-{}sjf6aZGg5g0z`Gnb{oT_0~ z!J2HPz+$I)jXW) zd&`^*Qp#xJOJ>^X(z)4x3jw@?q1U%Mx@hO|GY(hD4xfTk-)QL!gQBeKi3=@TULe>@ zBS~Um!|v&4OUXz1>diU7w?_^_Xrl#oxWfDl)0fuT42fJwvUmyG^87 z$XYLgqR6h4cJt#HvV)+o;QW=L@Qi{1fdXe4(%tEkGM&eal}QygkY}yGBoB_?JG!`Z zZF^GO6X&bvh&i`<*Nz>ef~iVhwvRoC8>tr?q+&0HW7`!i_y7`1It#~=3=K=O3FW&P zP~3J5iv>Uyc#lDxT>a99gV>9|p%>d^^#&E}ZRzceT4FdIP_O2**(*j5Is9qT#a_gU zXNxaJ)1sP88#~Qx^V(M5f)`565vy;E>^08%F*fxtrX;W6Tm?^+u8nuXSl4Q-ZRbmy zb468qk4b}bDcc6rkqM5YzVo`*8G*ncaZYXdDgtuDD-GZ2lhRlKs(ehC?C`p*fovW4 zmulZ$fJ1)$(e#K;dB2S+c)tMf1g$4xA(xPP9VWfw3qCkqJvZeS?sU6;sdtP*Yf3oW zqNhx1(Co2#I|6#E;TeMwX?h0V{s+~$7jLK8Bs-bIdsP}e8)WACTsBi?UoenTpeT1? z!?O#iEeerG1HcGvqRe?%WLP3-gU{x-3pn16EVBPahG5DM?K^Yz%jXp9l`e~<1IT)6 zZR-Mfugv{ui)~wZ<9OBh^${>;qsa1b)T|>nVHYS1Q&|2NZSNfwWzwyW;y4COjDRQ@ z5G6+iM4Qk!C?cs*az+6`l7uD+4d@6WARt+wp;eM(ktk8gxs@CQB(~(7)7@`_GxMEu z*1h-q*1i9@mUQ=9Z&mHu;n{mX)lS3L_iurP_>yH(=zHF9$J90Ps3d=jb3mifV^l1| z*7FohI$6<^H)~E*kl~33)Kyc}JK``-Em0>A{Cm$KnGP6I@WW9Z;6;0aakJ@E}zOIDFVVF27j(;=y;2r;}ss& zB*~(!$TA7=IEe7BFUbwZ|I`Svq*3d99cvs_x~e)Fs};?nvewKnTm_kJ zBsGyppww!VD-;&a3+R2UYWF{EN839Zo9+N-X|BjbKlZ2#EsjZAJ)ab91UjGAT5p2q zQ_7RryfP_3h|0d{?4}vBk;mYIDH<~RSQe6SEH@S^dXFOM*j;aAhYAF3yn=|8qt3_9 zL~I_XK9d{r%#TMLF4BiL=eDtnra_I@U14iW*=ok)|6M?yhi7p-dd$_6^FTb4yWBsm z27xKRN=*GbnT zCr?amI`27aw^uZ_yKaYA4N7S09)`hpY{RZ_{1fE;vti_|CzChq3c&>=PTciMcS5Is zMh1%`^lkxsesUau)|0!hKd9htN2}X(qOc279jR8J4GIa;pPLQWb zpF*UJ5kkr~ht{Zg5l`n|K_R3xAvM_Ov;xSj_ zSosAkH(jY!FN9P^gaOM8SgW8Z6^?jmjR#;1fvn}2=eKFU1ul=q^Pu5s? z>oq(uC-95Rgz#-&+^c>(e5eGy@xud1-n1`6Js=UpKeM=frwJI|ekW$rxCiM7Qo6U1 zj#u@~5kn)*eNgh?Pdb1A!pNGJkrsx?@#GgHWYM9GJly8Q!Do3Tt5?N^qEFCU^lr~C z8b`0nZAn~?u2IEdNYhu4?&_W8Axjh8>ltpAVIRnaY{Xe^e_3SIrVE%ID*d#b{cY%X zXdXw4p&=r}v*2o=YMDI7Za}J}3wMEe!$+$n?IV3!yN~@9Yc}x;15JXj^d8%L#-xc3 z*H_5OBW16M#F5_|0PSF6{%=oe<&vQW5kAIz0;}h_N^XPRje{Y>mTixsXnD}+*v3x6 z(m@?dr}2LoDW3BzO*+LZ@TT--AMUOnf>n7vfrE_2$a}pv^;{&Eb@{>S=<`r!&??ERf1*g685Dc;54miX%Yg^25-4#7^!nK z93S3|b$5w$@`NZRb?AU@Oe=@@Qhp8P)e(Z2xo9+wycZ)I`FG#%eFOKoje@M)+IogZ zaNp4!((ck>JZnV$PbmOH+8xGv;`tv#_c<)T!1g;esO@hZqj+rvI1kX-giCz_3r3y| zlsemy?htx{8c#&1+~;ro-!cQX>wTx$Hn3O8rwaO{IqLdcha8q0Kh~@<;y&AguGLR_JxBWEe(kpj`s>tmH|Im$CSND08k0S5g@Y86nj18i(RqGunx6 zTUG;~4pB+>QIn-Er6)`$z3js1rB`SABU;Mpp_T@iQEbkw-~p1gST1QbIBDbh;v#wA z%wja#2?iE{XwC{zr8@DW804N5vz>f=>1uE;X z#$FKzQoKa#x>3P*fpf2Gdi0;l6lbyarlzUtOGT8b*0U6Jjdcu0$u>5n>>wn@lkrP( z$J~Io>4G~GbDC}Z$*EeJ^&m@2g1yiR9x~MP?*kvfzbAhSK#_Hjanb)kdU#9ze7iZsyxwE+o&C{Oa=!3;snsEgwR6cb2B1Z!Juee7zn~Llt_v>^!}}P1jROVN z`9?~~1Fve!#q5ttWxm>-+TJzN zO{P1&DC0I>6`X`E!?26VyYH_TUu9ij@A7v%n0d(jooz%HDd9#FZ~0?Fv*X0s{N?&4 z>s=v*p^(n@b*k9&H`RuK&L~aqg4}IrgXki0-^}4I?08;}6avhkBKxtz3QLJZwIp*U zVc*KFN+mWoc^v^R)vnm3MC+r8$IjXuIw2DS<#v>SPv_wZ)@3^Me=kV)jL74g?Cn z%b|%Vg#>kmK9jshBtP$4j*o9_L`e#Ji&`NEo79;yIwfQ}oFt>g%{ zt%qcLhuuf>lv)4b#J%JRAF0~mX?&2Vc>n)~r%~x|p2lWU{pw$ILIGs3(D;LrGcD7R z585(HF(E_1V3hnjAu|ze+_-uN>)Ic>ix%-3B3;?#0yI0CSG~#7yLg!$`kxrtV=H>Q%fi^vmi5leQaKu;g>#g22*#fUQ5$~o>l+r(qXw3p|80f#?Y&Xw%hug+V+#EpWE%tpSiCK4A2nNv_k zcsG2zJNAB>$juA#h)&{(;CErr?DRU@`ng4uLA? zE3TTEQa!!&*@idb9>u%N1O+(c6eoTbH~S!d=_WKfOc;M|s*PjNJ9g~8NljQHw>p z#QsJjDRy3QRCaz)6p4J ziAhOP-m2=3dGqZy=hAKZ?X^>9J#?)^gt8m!S72^ADXR+jw>@Y(7F*SuihJlv2+Fx+ z>in*0lN<#b_au-H%%@;DFw-&?$nFK86Yh@w^gKe=Ma^v(H$QoGao~i!@_dTJq8X6`K z(>*A?aOC>Yi)~y7$O1Wfp1ro@0 zO`kc`=xRD&1)3}I<<2=5K+d^3h9RtS)V8yZA&#sF*0Fk9oN~7a&ISHmWF|#;*LR8M?`1RjjhP5mxwd zcF0}KOJrvU@)ckQRJR14!Pc@F?w%L=FHL%x4`dFI&$)RtF)=s_2b9VDHiMPxQa}wH z5)5N0qJs1iabrot0foQGv~y93;89~%rEKdoTUU7|G+xxnTIK-bjbbuY8)xPrEPN4Kr@yw(0v9+N*Chw!l^&hKwOTAuYQDkk-3BQ|Gmj!2rPkvoR#e8N*vEPwAVRw789-62E8n3 zH4x6~rc{rpL~g$9R|ev^nOO7#ZnxbrK8!N|UP@611E7VO99(&91wmf$918G28o5czn0DaV2;cvq z-`5FBF>BSIU;k-mG6AhtuG4OhQ3jTrTT)6f(K79<1i$+0Xq+IF<*Df&0}+KjzPa}v zqE}G=iVC4~cc3Nu(!ryarP6WoBZqm9sKwa7h&v2Ld7GR+4e+P7)*)HmUny775?duZ z%rf`~-MXe6`mAq5ynbC&md8ir{61gB*E>9@iJ_Zosow#-AsjXS0kuWWS0o4mi7Zew zAYn>z$c-YF;r_d`hIfY*!A)#VN(l5T=+CfzS;NFVlbr_z=8f$2SxITO;(iaz$%{b3 z8oB5&d_WB6FRaDFln6_?_V&SZ&P5T=<5N)bQ~J7{>X{^u@7cp~3}+==${BRuK)dRh zQVE%MeHUdTA?;$7MnfSy@}?uJ_`Zh^5np>Z37Xk-$i4L32VZfN+>A!>jrW9_`riyQ z1vT@cR}$N*5-vvFR&hM)=7gKb{(*&ts9(`Kp2gvIV?BES%ks6_EP+539y=P z5zg@5mfE=eig<&M2=4dmY4A?Zm4KJRZ9*S!&@mN8nyjX|V>3?pdt zPx%7b>EzS&tv_4c5yDB=P$A08gD9^n@D;N0-bpDp!X2d0KOLbf&}nK?lX5cs5t5TZ zurXwHp&E1VU15VIR5;(2rF##rFoEcooyEtofZK9+D?j!c;*Z0ZPYZ>w{VMwuUEVNO zD-cB*UgR3UD-@_|JolcG-nf)>p>VYbsp^I0qu0U~5;h99?*R;A(z_k0m#Tddbi|QA zN1@;sUbo@Qx{Y^L?974Z5wD(RHT0uE@?oJe1NzR#YkS=m+g{mV3r-aM0l z(52P9vAe^-q(`HFC2qLz(Bm2t>I*w7C*;`g^?6at%>?rQLGFhoMr<;&;!O8XVO7&? zZ~es1$vYg?^o&3LGn)me9rNW+P*XdVVrRm={+Qp!})0f{k{Kg3Qm(WJtfy2bq zXRzl)ygH7tuWOf*Pl@0_lBF=O&L;$2-)DXZ@hq7ZSCost(cOO=$`;HE?{H62O_eR9 zl2wFb=1{);Y*x#?E`5t-0Vq=m)q>hc!k68(QR#kKJw1VQU9N@uh5@sy1bbwTl3lv6JHp=-~_kHzc*-mr- z+AXfQ%+FDMjszON3njnLyIV2JI~=(3r7A)d8ZZnIFbAaa7JB>;g{p|K`b9z}bsQ4Q zeBd@#6o|KIwEE8A`_;1&>OcFgeQ8KW{7=v;G6yK03kXAJe6#9ky&LW6Q7qE9&$m#T z_{Ff%Mh!l-5^DDoVm%R;@g?4^J!vBEA8bk+{7S$(u^kU90$GGRDzmotFqS zOP^X#(g1p?USPNWMn&Ux9yXn(uT%u7n}SHW>_?XNWnb@^w_hocJT%DZMd=ltSTX)5 z8$Zu$vp-)daQGqqCkfRL+=1Zcq6@JtZ;w5#A8ifCi@4oC-{!#I{i29t!32#I7{TU# z)1{(d-J8{#cC9cTZH$S_eBaKCnlbtCZQX6$;>N^0RE-!;~c->2&FAR%=^P%SqE7 z9jbvH6}%fb6>r2PL+p-J?4-gt)aYYC`;;H6pBjx(sB0b^1k;#5NrczqRM{;RxS%-d zj(4@%xCbt2$CrZ%OLBN=w-6@amUOUh%xS$=9Qf;tfulgr8}uXVAR#k85D0@@SEj~8 z2}Ro_9-hk)jN3!@q@Ex&(yWYP98={-$Z=~*cFSt?7%!~0xZMM$TkS4B92mq5z3k!@ z!`DE5@LSMD1ph?bn~NXcBkZ_i##KZUB!mi(jQe1W5UFfl`E%zq4jQLci6ZQI-u&HB#LXmY3+R=FnbubjGw^~t=aAsMB+d3;Z@8r@HI4z39pXO(ptp>Y zxIQA9xf*XW@$^h(q@kZVt~BIvo7DLuhUASVWM4o^{)M*%x-HGguYz`cD-WjouS{lx z>V_hhU2DVLuOK;ET7?Nlo_5<48UQ*3xdNoYjtGxGgBH0L$o8#ha5ZtVB>O_`wmrE( zaV(0aFgspOmaJv$H1|> z5ED_A`spcoFt?cM;?vJx9N`HcW^>Z{4orX`DCUL?z>AE$20fDTJ+5(^gfwbk0$w}k zoyo017T~53H+Zj@tS^j;NY(ev+MsFT2oLANNE4ag7}$nI-PnLK7?B~vM(AD@^i+$r z##5s?xbUk#ffXIL>AoAAW{rLXk}0@&kz-HmevMlQ$1{BqG)n>h1lc#Bn|oaI)u9B9 z6qW_}63mB_Z*Kh5oEwhVc~M18JBha4QSJt%A{y7#Q2E5SaQ`wJ)=U6cVWWJdjVkJI zAx8Ok#0tJJv;imYM9!h(^vZLShr(ijL}Qq{;BCMCm-_OO{tIlEdQWad8=s@-^wqJa67{n1&||E+xNWm z0Q0;gqpPp-mI@cSrZ?cxGb#BFLuPP63W0IwAeoyOc{263GVRtyoGC-ePlGR3T@sy& zndBEai~fZ1dj*_7GCPwwdV9hh2guP%#@#tdz13iO+dGbVK^){)84F4-RI0{@2!e`6 zwmI_dUPi_AG!7_UToQqn4hxGYIlEV6nUVeLH*OM`-XK8-DvOW7| zJnnku=*(Ole0Z1;RHA$I?b&en6cGY=e&p3JV?g4Oy-t4o8(brxZuLsya6+kg{ux0i z4`G)7;D;uG=MFcI9>Dc2f-BTCLvyJ!^G!%ks-j7 zMn2L|=u!H$V->t^5XMzNm0xu}g`gX0iOWf~KpH5WnHN|NP|7RXper2!=TRncDGL0b&@( z6T4XyutTyY8;`|ZEdGgbKL7nZ$oRaP8GL(p6trtGw2CDct-K?VYcdfQEcAgVjNyCf z&*^?IvVBJ(E>M0_>=%0p*hPws>NC|dGo!P!VDZ800!aV^Tvz{ zf9;Km|N0Q^$(au!P2nwL?u_Ta|5@TWk1P-e3p1l|H9ThQ=m`4o z7&aXg7h_Ym2U717RS0mCe-d?0BW`SX7a&jKR19aglynlV^7Etam6 z^QXPWmBfA7#q*4U7EFRh*Z}+P(u(sL!yQ-mN4z<6Scu+KFya+WZE+xzd$q6R6$yW) z2pQ*K5!M^5)|U=HIAVB7Uf{_qXGxpk?|Vc#YaEQ0@CQ%=SE!O2A2%x5C5^TCx1VM_ zWjk&Q7yh}5_Bjzqt7rvY-F)*j$P@l+?vf*Uyi|l}{P$~xiRu6Kqo2I6&aO6tGe!f= zRAAFUnXzp%=otmxL8m%t=oT(S%nJ}i#ZZ^M$^Fhu%5UFZTkRETFY~=y2sH~cSL>% za=%7k)<#a2;Y%QshaEw*puzi|cf`vA2Pk&<6OgY%`{EEbIvW29MG`N<+D45JBS9Ws( zp=8Z7U2J2WYMZ#de(`v?O6lqCDDiv-^zTgsY7vnH81&TifBbe9RYi3!O+$KiwGX#3 zl$NX+fFcbMwnsKR(#>9ieSuX)CMZQI{09L$JeHkRPuXtGYb41$)HH0#isn7msCTLN zpEbPPvNVXbcObHcY6PGzP#aIrmyC`*`DY^5_62CtXpQthdda+$nog1TZG6c}o%q?( zP+YC(GY+!M!}^R&V4Fm=Od>B{Xk~V~XtvWRzPr)|I)wQFAA(&E=Y>|>>Tq9<8C*c} z1PScH`T_lcyR1-q>IKDyR&m^Juuk5Gy-+TFE7)P{C(^6;Ygz}$aXgvy=;o1y-Veyp zYMw`le{w$6SEO*RZ*)H0Q~abD$F%>?A3lZKG2`havy&^oKi@v>+A%79*gvi!fg3IB zHaCTEa!Z99U)r~GtpV770UTl8*D~6FT9>G{Ft~`S65pOZsn?~q$W0J&NW1t&bM|ftaDuq5bwWPxp%b$+E^RSrd^^o-LEip4nX3v zXwZ2=*HNZ&-OBUjMutP7%Wq2euo$RW%`K+TsnyRDgsW-xE)K?h-J zcufZ5^!86D2R3Z0Y5L3&sH^#p3B^xhy)o6us#T-}Zl#Y)k+Aw?cf4}Okku{h_$?8aD+*h*H34k9BcwJpJ>&%}=_5YaFIpmf#WqTgcn&hLi zL#ouMj>CMTMDGc*Z#vox`>qL;-04b|2DY+8O_B}7Z z&*d6hzh`(smgi|c7yHt5&u6sB+cquwc`k+19r^YwLFkp9O zcp!iHNM3g=yZiG{FmH0Qd-95Ytqjj_)99DT?5`S59gaD2Ck1pv*YHhA$s6*d(<}I- z%0%j^&s|>9Dp0yP5NN=$iXThg7@E2-dNomI@z2zv?M*ohawioM4I}%`4rZGUxLW2F z2HJ$fqnTVDoK@nctySiYI#)PL8#N{e)%AlpO*#`B#Xx{mqVhdsLq#nchsm>^{b_TX z@dLB5pWD`8oPu>JY3OxaU=OF?tN1A&w?agJ0;dOoef~&1!~$gRp&tuileg>-l}Po9 z_UhFlJ^h+H&>Lk@sefEv`kEnU7>262|F7(h6XpB~K8+|7f>OSLabw}DOk4IolCq1e zov&6Q#&l9UOuaE!lft7%LI-76@J(myH0(k~u`)!7Yc~30cSn^|gw45)z1=+Bm<5%sGxb}wR%()*sR{3` z+`RRq3*BWJlYB;1w3bo+=fshV!y6kDD*~p!7g=5c-xx9DWG@3s0?X&G+N4DY6kMoM z;}2Yr65l%|;2#w?d;| z4ZQa7&>E-m(bEvEyeT`Tl4{c?oVFs?H2+*rXB}VRj$irEzs(>`4z_kB3(z+&Om(v6 zR+QZ)@OiBhW3h~3MRF{fR%T~yy92M|C zV-|O&^OWTo!Zh1qrna)o&Syk0pwcUgJw2JNW#_~lA2R>f`Ke8f8hz@I$h~yJEa7^& z602#d0*76^P7-o@d}Py1v(Ha;k%FhR^0O`dh#W>2T6-$c(dU$04h@jl=T}oj>E)!QZ_bB=8B>hiWl zW1P*TVE2wBY+f6Qmg-aIL`*raL4|ako2!prO^HB7GP~X$-$o!MLcvWT>|#u8tlyg` zc7{2!fB{X8Yh=e^E+-pWh~wjg?uEp#^DdRCV4pdk(7UDQEa z6bXT=tsSItg#pEH!Aq!Bu`Db`N4m6pJ)|9aflK&R2-xwZZ@s-+*k^_g%M&mj95eAy zICE+> z2sBswYs^{kuP(8KRgeT{ex2erwjo36DH4oPuvNGt=sPj6Tq~(u_9;Ve(tPW(K9Vo~y@LhsQ4nr`&IZ ziv<3qRlbsFxm@O!mo**;I6bl!c(sK(D&*)LIf)npoC1USYSAYm2g*CI$bSoUQPc9u z7>BU+{LtG)xgDfxS2s0~QhJIWmZeo=JNlAdcLuusHaMA9ntqb*f*wcK6jnd;B%z6E z0_de%#ymyS=!BEk#=zm<0jhSq$y(A-eOhPXwzQp-v~`BI>2_rJbn)UXiBGmpGaG_I zY_l?PM^E}?BRqR2)AKd!b2Y}X3~~y!c$Ny1`Nxu0@Y9(rtwYMbtRCLmN#R4bk2@g{ zkOU~zQ+FB~-NrrE%J)m_){1Xq{Q-8Xc@-rKoIZo*#T}+Ju${6#>zQq&a?O-4n+hAk zgiJ3Yhs};un#s4X)*I^{@sQW*G>rcW7Q$+qtSA4rjVdRnBkPZNk?exwYt27Kb1hNJ zBBx?YFJnW6b0_tjvfeG{;>TejJ{33%VLvI2pEWP_ z)Xm#_fW+6*D$>8CWf{2RaPOXQVEbB&Ge-+Bhf=UyRs89fSNEvrfp&5*3}kt!EVeBo zyD3dEGK==nH&S_#3!T1UYMPhxo>nKifoE!rB8295L@#k1#9;W$w!{Le&!8PW2irdi zclR`qDM@$YSb_j(a$*7dBv;nk8|-#$etfR;+js0vF2<2{iQ~j7*1UApKf7k6z%_Rm zn-mn*wuWEPs21OAec)}JbMh=o2Q*$jW+i07HY!bgKLl{pQ#ZD3qj)&s@|>WQ$N3_8 zndD2NkodG&i*2aktc0jays-4eDdix8Q-=svQ+l_#z{u<79=#hceUMFbE5y-WY31=? zWsAisz9}{a?@1?qINbPrbY#{7Trt_RipMAN!{HEnsRWwXX5{c@2|-zF4C1SMNmr0o zGsIIuJn<r4@Ih$QyC{?n++_Ub2xNDT@0Q@fe-GOBxje8v5b7~>0gfTMMET&^9~rBK|ccK zxa)rc!dCd>{UfUGn|&ef0qi{1!VXi~D+RMG+id>R?gVAF{2_LjX76?56K)sK=6T|A z>vx1#XM-hBN|a@k9wiyyvkn~y7af(VB`u6#y&;^W4HJYBow_fJV&66P z_PTCIzMe??Qe{@Prd4+%m{1ZdLJ+!YYWEsKmd2IAPU(Al;5}fVWCA=Cx+#Bh68zqEvS&%@ZPen_YGNo-wZ4 zT5{WHV=ZZ%#8Sy0FNr&qFuT4Kd6lw0&Lj~%?%|HHPGf~|m!0(>9Fl$C`T*V8-L0T~ zqE-%x{lNXT4Vyn%jAkUzAUMR@TxKrvn~@(_p~qs#Z)k3xQYy_0TKRn7(gDC2R@i@j z>V|wG3!xb+b?i93>=JrAGII{a1c&;_+spifXQQp6vdKuW5}#z&@V{VyW@G<(q20LABe zO2*?ZOXfq^O5o@t`mv~8P^^VW*Ww_T{~9r>U^y2p=}G*8!(lSjvX}P}1e#1xX1Pkg zKbiS6Bh?ZEq~h!Nh4wv+XEvQrez@?lx~ydT(yVnxfwO&10p@q7l_nTd*#)DeWLwC$ zf*-Z(Iq>B5%v*%dDZBExjMPm!e$v7yiH2~(Wokk2^JJanncgAn6Zzn}5kB+j!)Rj} z0r5TeIQnCdmfE>>iQm(<`pww3H?F1`OOAxkEGbOf)wKd8J7hNPeis%VcHbUut7*62 zn$DT4q^~IOC(_TMRYL&+$(cza(H+1wzH-4-FZX_mp07o@^^f;QU~U?P%v35U)M?Db z@wrtvB$BA-HahF%~b)Op9mz)G~a|!&TPp zHo35ZzIp-JCZ~bgkFuZlj9xd?Rwa~palvh-pJZhp2iJY!*c zTNb`tl3D3T82615y?Yrh&Lj3b_}G*E{0W{e`JSQWzqMkB`w7p&SMZfxv2E#sD>MeU z@mbVfx%^%i8I#(nnTb8V|XbKJ{#)ZO1hg>b6B3_&82K7q&S!TCf`EloGlf+M@jTc+R(3#_jm~Wl=ypT30VZCz* z;Kb*Ipq}i5lT`nGC?&O0M5nr*bPq1*EMvJFsjT1p3cS-id(Q2-x{}Ezm77V@g14q@ zkxAPVX!Hu*!)ifn&ZUi%?(?W;0&|h98%kKM_h}^JsC!qK1TlCB`@CvoamT(U5+Cyx z_{=@8==dEn_X24r3P2CEETWR_07VLK#~Zu zdcC3fQJp^d9rCNM7C%N8JB#Uk^9L$SfOPb5CJ#>5Vo8m5hOd$Uc{ob`-Y@L_Kt~$! zv8tPa^*B;0n-KC3^dwuj3>`72olgDzeFTj?@KE+stlq{Nkn_O3ag^=TtwkkqA%=Em zz7$csUR@hMR;$kRbRz(t(5O3Zr2eqN_GrRvIr+A@I7(yIDpv%q>xrsYNiHfC*y%?j zdj()&D7qI>lvPdNjDE(rRzYD|abQaLY6Mma|tIyGI-XZnU? z{6K}?QPuy#y?wnMZ9F>nUe&O%BLw!58*CX>cmh#lOxXKqq|>;!s4#&>p|D1;t}Tj4 zdBA^KaV5qsVef8>=B}Z;4q&K;Zb4*@VdH!9LjV$>On3;fif>sYm;s|<1U;L5)Sf~A z^HIU%-F3WvKv$QCaz$2nnhVCHc{QI5oc&w;>PXkFFkIFBNpYkFKMwX@oZWwBf0*|XSL)+4~xs;J;#zC&T{FPUq+g&bPzm=OD#R* zxd4TLp{3<^Wq$(#FF|4Cy@No9-!xiX^K$$sR6WB@xBf{a3u96XglIQBM5PHz+Lfxg ztbB`I7WZsq!dg{IRdAOd#KARY3qKk(e{w@3k5;@7J)bNrbgRl%{QOZIMrBZ$(&64@ zd2AAqQo*_=BN&HSRCBdiz7!p)9JltSt#{j%H37C5qg7`?-F}S1NcO#f2Drhept1Ml z-JZ_Z$BPcE;-}D#%S%ge(_cg&QNs-7y~<{779~e~Rs7M9gYM7+vd8A=jj>||9tdl# zQC@pjJ&1$)IH%ONl9DwM_|VZ76-%WaD1czfO$pcfu{QOJHIGh6-BtoZG*}j`a6Koh zt-pL!DJYG4Z+Q{-+#18mlr+`$T@g2qp8VZsR2Z~+-FAdQH98^hcin6+6`U`=Z=EId z2yxTx@EiTe4E38z)W^b+5Wq6;9*_OLjQYoE&;CCH-;hF0(mqvHwLR7SvU*!G1qH4k zbjMckbmQ-{k@q}n8Bo(|I5H4d7jB^6Xd4Ay%m3ei9HNZ9kt@!IIZs??1$!~C3l{luS^`>^4Qt4ZrMQEUe5BVrYBiN&>U$9*uU2W* z5B2x}fW7{hnty@AyrY>*3N0}^A%h#-VBwrq!IC5D29e_`>qSFXFHBVfUZtW}FvbbB z_(X}Vy)UOL6=$i<%IYsxX>v#jRi3UQt=CArSe!8jBp=h`?!&JZPr+a{+w=f5Hh|Ds zTPlN~n__yS4IGxu^SZoC7Eb}KLHhUR2Ai@gmiIZ^Fi&43$hBw^6vyNWl#y_rE=+qE z-`b1Aj26dft&c#o$g0?*Gch=Nxi#Uus~_yRR%V2UzO+r)Q<3CJ`lvd8%u&_jv z0D204_RWW|IZ>y##&bMep|k)!&$TyLZ&MMs=KEe$f1jgrTQ?3X*>pCmYr(sSA=Ve- zj2l6jfH^9^EBTUx!x*s*#ci=&mVKM2j^P`t(fFv0yhY)kGTi}HB9|*n-;JxN0ed2I zxoT8dHafwvy1|H%#h#uEqq#M&wIQ<=#i1*?dgul67C`^mecsJ=`fB)@+gfGJI2;$9< zN5asPRwBgu z*vdl#BW{~V7V=TR{mNDF3QpFgepS@fW0sX7 zT1P?d1S}XbZ9`P|%4f-(RA!L|EC%-*jpjump13PFD>mM5c(DMK&=i%PhJq3EC>4wZ z`rX|*K5>)%Ak9zL^Q>kH(sU(bgKv5c!N@yx$;K9bjG}V3ff~s&rKJ0(tV=!Qs8$;t z`Y=R!d4+1^CXBG(uCNxJGA>24p&Pq8uVjdNS!&nc?JT@+qeD8tcVY`1%X8F>0 zo5}n^$o%Bd%&~G?u!$TXC^E@qtec)3R(cW7F33bp_C7;fY_5ClISHLq_vjU5lvJ zf~+OxDz~($%s)zOlBke=cO(#~z*)^lHHELP#6bV^O1EY4ImT5i$<@G?L^3OxAFhaU zn_i0y!tL1@SScHzTo40Xg3vw2=vsl zPXbSK*h+nWkUPbnra}f7U*A_WYtV!Qg1qLT+@Fx8K_9;SQMJ9i=!vP=;n^?A{!zQ{ zq(qosicHV78B!4cq_%d6+{i_)ua~PKoe_7;Qymd}B-MPkbQ6{#)2Bw_#tdq<(5IVHnW%>^1iu}vnhsVl=0H;>crSGhJn>#HXAU{^XJ`=_RddiaeR*)j68C|Ch! zUN56l<_D@%aZ4g9@XiHohG=E&R&k^S{KRhQyqc-PMV@QWm00&e+37X4(;G_(Gi4 z8``ff>^*$oUo(D5M7hp7a zj23y`@5wV|dS~1^Jcys%7N!RLc>^EuZq7t$-Y5_~84#FC7VI?FiO2+C7R|brAa=mX~=`XwAN~#3=PTu&$aV&c4=d%H} zqqtI1XS_xXDG3=f1|+%cs$Fzhi_Nj`(=7tXv5HKOz% z_H8c?K^v{aROkznHv@89*&hp>RY~}KG}{ayakitJ2q0BzPbOKHBa+-{v66?_no}UD zNJKQ-q2s|ft{JUGyYC&boPPa**A4=`m?d`(Z(^$^e|xb9HhTO0NrkIBCu9Y`A?mcj zJnK;A76o0h?Y&{VZq2R9FUlzy4|`Ghx;h1bZE0MF<+eG~pr8q+7})e`xyaW5qyv z(;$z0rnG3U#E7z*S{$R@3Ie{9%a$}dJ553TjPSGda0t(wbX!f}1w!^+$ZwJcp{|T4 zVbPmIy8Soi+UcPjBA?k5R9pL*6U+BQ-g~Xrr_52!?rB~Yx4$XtAstVo^cO2O7#$Uy zt;btM)A)2Dd$RJuYyFO*`l!gAj@TKljD6(xQ*b|n8XXvC%Wglt^A?B{^z&uITetF@K~bBC5xCYN>mkzcHn0m--K~5X(7ElQ_qIZCywo6 z>LM!cmYA8y?W(rqhcbmr=jcfGqs;GCr0e@06nA|_PBz*38|(_K*AVgGKuX~}&4kIt zbmF9WCfv&-Z^y%|Ly7e1M6b>Iu0|e~Z6zB9s7u)h*?;;r4`@Kwn|9q>%8|XXE|`t? zWl=S=0v;PRsAO42WfjE=<2==pn5HSsU-OEPM~4$n1ze-3dnm)<+ny&(wv8|^yvaIVoiPD0kQ`U0Yt#jO>oXPD~nb*)zU@1df!hvKxoWu5B_nLWo94$;%CMI>H^6e{^-QvH}$`0QuK(j4TB}Z2&CiGb? z+vMPCXHkeHX~D8${gWhxF0;)R#yFnCSkIYV8PZsz1&ERyGDr_OPiyz-Ylz&63tBNh z@I*1Hv!s4^DHbG>l8n`pv8qUL6*BVP{AFLrZ_{A~{Uk~w27`0FOQLhTwwbA4U;lH#fP&FX6 zrZjdGDV%&|Qsormx&ZkK93=!rmmF94@fh^{>2>^aS_yqOP@T@}hhj3%)|By8p0x~Z z?AFLOO3KPNwRWQ;F>T1;2xLrMSE^e@>(Fl|8gk)2^7(DbFuobd3KCLYm%Oy|+S%zD$rzaGji z(jE0xG`Nfqysrq4wwnu~PXqnZgBfxq{=Tlr}3?UYlLTYnsZ+IPgO#n#Ov0(pe!89ph^2N_6FJw5^8>vB>e?$+LjT5l z+!tyE)tYeiIiEqQlMd%IdXpAj@aN*ZwZ01e^ejxuB{uP73=H25Kg1%nr^3R@M)2-^ zQfUo$wMwp-Hv?M z@mV=r5rXHnaap%yTZZNYu}5`5>hDevg0eGh2Slv4f9m`XZ~KAhW!y4!`iVP{LtYgH zJ`{2Ur<705>2o_^xYAA<0S*cyEH@Rojy? z43IMUi8~kobPnQ~n6=-0lG*pF1`5TRgLWuYq12pgL2-?AQ1pJKJ%M5j%2^QE{reNY z2dWg@g@|Xgli(v8gCTR7;!JGq1CA#~3!UeXwp#M{5r4vu+Xf(csNna7w9>Hp!N!f+uFCCi2zA`>K%DGA7pe@?dtX!mhvQU@qf7ul{Q7J&!<4}suqedFZ1 zzAdo_&tD8Fd;bvE_QeN?rh@S4ox2wAAZC1xrYKc>uZ?2*Gy*g$dmR#HVaIMR^ zy$^r?&(nmbR*%S$%fH^e5r=C8e5AKFKzwtkH(Y>^Jn+9k8f1d)yC}lkSHzt_E$tAF z-{AR=H-w_&&u})h1Ubpm`DX@uuLsn?rtik>v$YXBcKjb{L@XjwI5^*Qa>>Wd4PvJp zVWyLwXA_B(3GCm`$A*~ffPz4^zKCL&u*_hK-1DH(0O`I&)&?>RE#?-jmXd5kchc#y z$8Wn}9PYZ3{U-qnLd+L5!9Wi29LVc2NWeWAd+*= zvB}v%K|xSKk~G~)&WJ<_q97T%C1;S>V!MAh+Thkz*JAu_;_Gt^A zykIXJlUg*vS-uOb&Jg_VU`J5A5Md<}|3_#6R2I}HoOJh}Er$paSAcuruW1A3RaqY; z2xQl4c_AIUXjyw$O_%D-y%ZLYt@8Yq)3o-Z0Vy$xcg?Lf5IeCeact@uwe{rwcYsY< zKB`3EA87Lk%t%m$33)Zu&ycqT61!((Qzl0oL70$)7|>h{^q-~O%|~ zZjMkd#`=}-zZ;}WBp5rZya3TLb1yt=tfh!DpICcm`OH$x2+Os7j+HZfhiCS!A6zDE zg?X=GRnqO0+7lJ3LwOa){ki?#Uk0&)K?5s$P*Q$LNMKG03qJ*aLM*uosWq+5EdJMz8>5K=sxXV_g9%zbocTWqEtBGt zGqb9!_oJoQuxK}dyugrLK8sP!L5>~1yVVt9Y?ZMALYb8P93H)`V^Rc_+hhw%b=Re= z-7?2xI0!7p4}ir$Y#35|DSyN(aDV$3SSxhzK|J!9<15N@b*1*8o!+@0)IJYqe!<_N zv(0pvM$u@XQDphxV?(A4m0cwry#fC!TuvFpkx^`HqlW3{-P=s6)=78QX7VA1gCGz< z<%Ue^ZfvBI3shxo3~7unzVhOo;9lCY`*_@f{AN~I+H|%TB0eGP{CX~A(g5D{gG5Q? zHmciuzGT?YUtMeiP?2y}f$E7z>+8FLGN+{9s+J8NZI}^C}PY@IwsoJnA`UYk!KWH7|P6 z4%OJ&LS5Q9p3XY%(!*E#_X78|)_)^ab|#E!Z2~#F#_fX;y&aFs=#ogQO}w*c`#JV~ z)Y=KlYWy^T+*BKIu{)q0@IXsX=VR=1TwGp}E4sxd?TJfFz zBi3sYkN0N_)N|sO;TupXEY#^;6f^z2(pUT){h9%MK)e5|eNw;y>r7De4QLQ>xuU6QRwuTFQjPc0b}y>3K*DQ8q*;Sq<%$J-7XvA65_J&Ql9yyVM%#bf@ zt!|k)2V*`P(NMuQ&m9!Vmz=|N9PXiL!2S<_t_impfitt;u^K#1w!wQRH!m3vH)Qs$ z&+N9~O`}JgPR{(A;(H!pohsa?QPT?s!I)+Ap`{B?j7JD8J zj^G?&XO5XvjbjRz^e|>*$}Y(){?-WRsv)&16uOMybh(CEHBCYioj0W#rP6M1bn;m~X#W!f?1plNSfjj)C8A zXl_Y|YK!eH^;b^Gi=-v<(2PBx&TTjv3VA%#3!=m*=3Tuzy_o+vF#Tk_=!iE4quE?l z@(H#ztx^;;C7R^^LVL;S(X?ITQ@|u`HtV|I0bDS$)tm_PnYs_T+;%({uzT&{F)61d zLK7a0>2M38as>0jDVgn+E9cpBFxnN@$E-#7qT1ikz9JN)LcxW4m(qb~>{!%JwtltG zO+Syz{7q7_rV+oy+h((;%|(yMTO4F3#-98HQXqVH1woF$juetB%M_bgCvZB%t?5Qu zVc}UyR*SCaBDIiuf(nmCG0eMn0*NW>Usd4wYCjzGp7uX_56x|HD0lY3jy2fijf{Ku zhTyc)lOOd7dSVLh4rJ-7A84nIsk{|_tZ~|(;{Yp0-Iap;GJC%Ez%gnh^c4Yk|9F(D zTGHLfql+m0+kwx&I|stfF8!R8blrHkC0m3hFCmxU#C4QMQ*^E1Rx6eg;H#!O(3=B^GEao_v3yS-@sNfK}{lM zh77AhnRmGadod9>tCD)Z2mj-`fRdOYzo={AKDXC=Nw1;5F?dU4-W?L?#Yq1qD+!n@x`!gWj(0ks!$IyTEci9Y#9Xg9`)ag6D4q!MiK~`|T98J(_^EaV+ zJi%YR?!(0cCROF6yQ&MnT^K-LufN+2r3FB`(9!uk*5QxLxqo5L7>~@4BRo(rO>h_e zm-zt%$B|(~@QEB79|Viz=$L{&A-4;`Qu|v|I5qRxNzB?N7*z`IQr~hRrHT+}O z{hzi3Xa2v(M9EGaw3V;Gw`*5|v9c1Nj+Bq56BeL9>tK(H)%^#NR@Y`ZPOiYA*E{TK zLa^rF%Y>YDK3Kyw;2M(0Pk^WBq?NYnrS1qRR|koZ35i<-ZS3zA9#fNIb$DGUD{T@? zfFSA#8qLwh9T`+4F_bKWKG6Fv&7t3V)DgrZL3FicwN~pBE{PDxyK%|c)fc=?0B`fs zf{+0ZmQbGw*mQyMOHT)$-a((c0l)#Gacx18XS_cB&648<2k!e&2N; z7<%IuCDj^}T8;~Bfh5}YtX9e2b$#T{7-tGK;-APQ2@+@q z>3LWb@LJ;@W}y7WiyUg7ZSpqHzmnLwyeF40oLyQIACnDDZMG}`Sbe7?T0|KVqWeMz zVit#c{O}<4g2A4qVEd?|OuefOWo7>sqrp*P3_%qEnfxKMWx_*Zx;=P}{%3oj_R0W{ z0K9g7MeV7S`+{-4^=-y*-3#~BqOn@md+)6k0}c9p6Eh8}lcpDr>b(FL`$*PtDWqdH z02qhzS#v4Rj0d%WuFQ&7FN`i3@e!+{3uic)avE>i^)fZw2jTIhdnbBNFF?oV=P~K` zH?5&8=YLmj>x)p)%iA%&gC>hWFSVrsr=GGFCm(wsx_yNTeVseVMDZ8k$x*2!mtJGx zj&@nagdLRQL1?&4Efcri!Q&Y8`f&{)@Ep9Suf?;p1n17><5=KsnqN+1@HdLt8rl=CcO;16in4q0@q1!Q!#f)JU{jh z*>xwX>>Y@z= z!f_rXz#oVm{(XLu7XNoMPb?dLTI6anXXa*A6ABVjwp4`Bjz^WvF#L`GJL+?1&MBtT zWcgxoR_<(-+mNXVagoXVarc*O{^g+@jUJn43I)Z%`@ewFQP?5zAdFDg982d-pum$l z&3|uotI9I_4JKW`l%biP)a@8jlg%Sj2i#52-qnem@BGiNhbu10m)RK8il?a?v^H*` z7W?Vb^9j2BCD-HKZvDMQNg39`Ou6->&`4uOVfiw=);M3=+w}2f3zLRUU~w_iOaX?3 zuomGfn?JG?lLXg(lif&g6kRJDy;493lRNa-T`33hq19zwv&s`Y6>P7GC}61kk=mQg zbxP`(<8zwu+8bh*_=6)NL6{R+Yu zNJg}AdR}RC0)m9O5VkFTAIkAKK1`9Da3{M8&$T$sSDfpV6kbE7!{X|)+qG^hm80zr zA>OwNdeBcnPBQDwN%yuFX+Jjij+nRY^yhz$Q$AEH^2krnVeC5O;kwt}@6h$~%@}DM zl@*_ZLBE1vTAfZ-KpBU?nvzsM{(Ep!1!h!>TU|S+EZF+!Hj)_vG%6kyvgYrGuID5D zsXsH9fjZshMB5|TM{mE!-OxQ)koW$XYBBRYSkKk0O)n$v@I4441uwRAyK#;a_ZoeH zjkZ;n^~FpbKve=>;-CGS>3*N1y6cdwm5*2cUb~zK_X{L9(t1c7?Oaewl2X48MYdqR zBd&EuW~J`CYgkW7q=TS7;Yo9+V0nMxz3b@4Nb&ddgi9HvvT5CsZnqWI|5D&zSq!9r z`C2;iY`F`ChAd}xWlM(Zu7{gDHoW8o^Vx*xcX5;;;+pdfFZY+3Zg@ZrjKY=E}FCP6EJ*=-j(Ha(93B%gFxU z5%c=W3Hw{;vkKIQ{npltX<{fg$}-s9q&_qI^){J70Ed8F%g5wmAaKh+`Z4s9Mi5n{ z^aL4meD6Sdf&VTPHBsWX^4hRih zg#(RlRN&)mUa&@Z$*bpYFJ!i=vCw~zIRYmINeT1RCk|HdhkvGAx$309H*Zm*;|+X1 z8}JuPr>Z&XBRI~#pqg#@{y;rl1;{M|#jan#N{@MZZp&At^qzZj6$F+?Y<(|v@`%L6 zea4;6d-9#><4cWuV^4*Vf4*^G)}|@OH>@V`>#ub z@O!@<{L-_{0}x)6xBtA_Ge)j*;%YX?@ll)l-jAPa6q2N z;&2sqM(Ww6*%oCx_RkPZ0pJ-uC^-acy46bw9vicWiKbL-d4{(@(hooaw!A!oS%qH% zn#mq+S(_{`y;iJQ5Im_Wcp)wPQoGQ?dWC#pMtOalBrQ4_;f8pmxXNpT} zAdvBwDwkiklf+Rxs<@n!IqVg};l-c0%}4+l>)$VaxGnZNYJFu`2GMYCO0Km6^75kU zh>fskE(QyJiN7uIx@h5q`MtH{sfmAyB@so*Uol8KYufiPfBP-q>n40MmCWm5?(pQr ztwoObQJ+5zW$ql$YEC1&Y3WZrvTb44%gr+8;(dgJVvvvZ{4fTqcQ@!GH@z)TS%;@n zAX};XkrT!TAF9@c$vnV5JDC9va9^~X^l@)0U3EwH1nxX6O zFe2kVZV;N~-RUh&bqahhbuFncdIa!!!6>=3&Ng{dj?*bI2__rN8CAz^#%mCYT)#DC z;_#e=yn9qiPjM7V{)3hPNGt*=i)BTUU~^Y>-s)3HlJ$9L&Gnjg=$u5r#en0QqldEDkd_gKnOiE*e$fj~%dpLd9*x zYkt&C2EOxYzCv#2gVE6uJSGb>8977D=4%&LQ!l%ZF;Z)7Hqh~GB9|6nJ!`R=lModo z_(f+F2m^38<=`Zh{oE6Z%A3HRLLY01LJz5SzJLCdw!Iwbz%|bFbIX2%9;(n6UZ`)_ zTk4}s{H-TLdYXu@ghLg&dM3a%qrF6*GgRIT!Z2JVzH^QJK9y@yj70Hs+x?f#ir>FjdT;^D4juUKS?k8d4eMqGlzAG5tJ=cs)Wguj;5 zG3F`&COi5#Y4Ef6;b)oY2z(CoP6jCr7S+UmhTVQDBl88Z-VN!gRtl$9t_VJT<`BK@ zVe_|scS*zAuE@|L1)*xgaRZ#D?wn^OqyQx`0spnfL+W{Vo*1W(yu#f*jl~CZr(#eAcIzv^3O>P>Z+Zrs?5E`993hwF@Rd~X?B6?z^2r9 zroE9Nv!l6vcCPAYkKaPiR5veF&a>O^d5-URZ)pXlOKfyJ-Eua{Pb=t8R{g{jd3~LX zqR{EQy{0@%I_&X*HWb(#9`^InmYUfW5#cF}HP+}`PNudH7)6G#=iegrN$4M{C~~wv zT(3H4Ra**W@!yir*nO<9`v|(|F0dHa&Z3u3M{jlitU3%l{NTc6g8%MD`=vHX76QUz z~PE?+%&S9svPf^0KMRDn=kP}v=FDF6XT><^pSkIwxkWrak!x%Dq zYm1NaLoFjnE)=iN6kA+1h#vLKZ%JGCw7H)Xr5RUxi$ty{I{X=7&__9&Axpkv!dF&Y ztyd^iZgqyDdp21!$7P@3OGmSeh7Ygt;yDV}tpCpkqPZG3j1P~#fp z-OIdqBL#kChTE?8hiZjWi?pRpgi((BVtdSuCqL{jF)|c?*VmB8%V~u*5O}kT=OxXV z>=cvk5>)rI<)&FfUo56T@2_egq^}rRopm0tti?=7L<&;sLQJlc>i%+Q zr~{Sd(}R)Ev-t>oPSlq?SqG95mm4N@Q7^#@8lc|=gTmbY1oq0pMy@r379rsZuiW#r+OBm-o`tp7piM zR)A!4$afi`8Db`{CH~+-*je*kH|T7T%IB*WnXO#`?_EvHy<^8nmF?@)C)PIy3jB8KT>ai2Y`oTV`6P#z;y|1 z%jBU|ozZXjmQk+Pn%DW(lz729t=uyQY-6}r;pQ2ax{vSA9ZX_DNy!p}nz%)A42IvI z3=$$k>W?A73Z%Z(B-_uUTWZEXB)n+Y2m2U=ZoTP;?5CZ*@XO>vslKc5HPnKY0{-vs zygteRLW`PV0ix3^6zbZsSvRVP55ZlUDXT7OZ?{zfzXrxb!~0YUo-ekKfIo9w zZtJq#lIU3IW2l9(ok@86X^iWan?I4Mn+pM2tzb-`QokWWMDV2E_Hf=tsk8*+I4ej9 z6(tJeL9W_l#d>uqmH27JuyLeJzNJus!d1w{02wzran~_gS)4Ku)RTyn50=-U@dL__ zo1tI~65F8@RTLl@-J)T{ZRl=A96wH#()4(K&)*_0KfVjpL;jK{xJwOBQOd6PY{u(Q zzZRBqY16WP_(fl1;0S++K`j&Ks!>0q{iwkM7zwb9X*q4JYudUTOaJoP)U^bv>rEc6PABtf9I11K?a zyck}N}XQev@>zUh-6ts)u6#bLifwi*>972xM! z2yYWU;R?eGPu~GEMrwtsj;FB^%Go6&Z)^lK9aVD&5re^yXH50o33}`VPzOeb7F4+HddB>;~ z;I4IwQsfMo^UEW;BQ)xb;G5kMBO^dNis=mQ8f{2$Q7|JNG@ z$nHSfps`=Oj3H+sKr0`EO96EoB-5p{5GF!i1cB8;uVy5MeBzK18$?Nn=RRHyP_%=l zpuGQ2QA!Vwu}VS1H+4(lAg2{x`S1P|J|$h`@n|Ae7P{Q5Gd@VXbR{_KHl9mK~2IPZQgKJVyuinrM6Ss-)z$T&xlD8|0AY}Xr> z<85vZ4kPklHgEh=Cr$N@ZOsgZel79_slZ%)u{1(M=_xKWVB(bk+ZN>dwe|we_^uIR zUK0Y=_Y6p>_Rm91t{_3&miGiN1*Sk*7}$k4fvY~o!Og>94bT3%XDSEbFS^Ly0;-pc zj;aD!?aWmOE*E4tk4$iGv=4PxDjICj$q;qs@RpdRF>pGacyAkNS4+K;|Ed_GDqnt& z+m^1~a^*4r6T7G(Ci4ikpdJfuIEHEq=Pk+H@(nV8Z0;pb$NBg}{L5nCR`9sk2IZv^c1{bBa>~kVi_(e0gn6*fWZ&u<*GO4fF-EMk~p-N_C9;vOSHw3B_yA$+k5-1Bi!UH;CC%{BYVy_N&2Y7>{#KQ_^5q^sH z6c8C_TPL!I`kEe+8P<>?FQ1WTP#8M>ETrLkMDO#Cq8GMiGg%i3YuSX2CRP(c|CSo# zx}Ux58pQAm=T94A<#X@Z0+IW?RvpAXjdo;-l%3F2w25xWCF z8Q?$;gc0k5#~(~s9Ba%PU_HbQcc#uP9#0pp9s!~ldw&RN<~r0GdJQNH$`X*U@vK7<_IpVPnTkm+=&3!V1@t;yP*DM#L6jDtr>WOPB3YSIB212K zOh870R+c3dh3i2;sFJBXyOjcY&*`Lzl!d{C_gtzoHY*0YKKU<6QzXG|LFGM?hbHC` zxnv6lGay;^d#Ea)&=c0QC6p0$fb37gt_-l>3yau)^%+nLh}WeX>|lAkYriJ0t9-m9 zLqwiaOb)C~!waQ^A%F2s^+!p9PK>4iP6cT4@&impLw|7*Ed~;r>!FXv6}RXpS*FO^ zRBk1J3!(;ESk1QJbqkS)Cbt5v#Kc&`z`SJMEfeLQW9o@5k4-o6%Ld;JfMQ+`wmY0b zkE91-Mz=2bd<+FgI+3G%xh>}$Q%3t~+Vg<(y)K;rb#9_c9vxgY1O4T{je#!ilfhtQ z5~Z#8*pWc#E5g0E-ScO+yBDq@fm}U*DZBA@5HX#GXX7m3CcaCNN#~djK9(0C*>zts zctVoQ#Z@gwHm6P*HlD*pTW-*&3yOBVd2-$7a_}p&XVXuEha|U3dG)~Ny>WYh3ytCK znT<4oo#2h@cLw4GTwAtvSE}(1>KDZQYJwdPHq@-!@+r%o^`4Hw@AQMPnRZ+5Ik31e zfp8+~ufLj_mpwfk52^usHOT`~lzlNh!%{qYP2-9%GE3D~^IWc6b=MA%a5XkHLY&aS zc{Bm)Gk6$q*0n;yIMF8ZLkAt1;n||e#0qkj*ijSyPRgqh4Hn{S#)*40TBa(`1ak|h^Q3vV4cms$7RxiNb zpL=FR3nPCIdtdPf?AE=o3K%Sj6_(CLB*{e<$OEGjJ8oY6^9(EqaooJl02bgx1$!I| zdrx+Px3ax?n+OJj?XXoPFv27`NJ4I(06$LW?72C^U^(Qs>Zrkw?@Lw(8i`nrBv;4x71%xg`t-0e}I;{8{ABsD1E#U zG0(gTt<`rdu=ok<$oRPj3uqqp)Ca{M$#{zMt3K9iqR)#^`S}q#J`s4-u^XG-++&aY zu>EIZxz#Vb;`R#WCt$FCb_Ns+%(1WBy28CbC{pQGxLemuY25~geWY8n}z z<7R&8buX6RbsDFTxGfxE$kp_E5uMsCVU@ON#E1IU&;U90wirF$-JC&AIc7rsirTbK zb0wNR@+!sC$TAUEdH)nlRaZ^NorOP}m_T_Q*k!UQlPf4$iYp>T+yG9?7Y(507k+$o zwzU_f9}FhiK_Qg%*6YF!)j4`HDVQ5f#T8_3Pt#ojcR36bm}7Yom!t}TTj}(TWJWRP zYeV>Rgbj*o~+hIBsrV2kbascTOI-)OGeus{4d_5ylZSj1Ky7F0JxHe>IsNDjpmC0>!o`hhe9i@ zl1CvZ#VxQ)=UI)=;%UJpI$W5Jv1SJVuv4PCnH{L5qxVWRX#>8Nk@q+PEaB@dQK7hT z=I}PWsEvbn0&{=YhTCM(I_<*pp>n9w4;ruphmtaJ3yuO%v`GAc(|zT;dNA0Hlac%r z-pzPhzusI6nRTS>m(e2s(A^nZj}7&GId>)1IjRj{7kc@X3n&YVHM|Bd!OREhICj@$ z@%rM3Sy?<8?EP#ky2Yu)ViM^!EjKg}5qIE=!1RAeO0z2GH}dkM1&~E9{hy!VJiEVr znRUf{&);QyM~t8bG{2N^(djS^ym^HWT1#FPQ$+96=bG7E`#Ka_}FMg`@?K=jb3icV*_%PACJk-8t2sG?2IUVZ_6tl0A$%8gU-X;)L}7n)1m0Y001?N`|6dIYavVF_VAIMim*N} z3`V69m^${~kK2X+eGlc(z-0kx@GiAl(~#M=K6M^tm7lCxEJ?R>6`3 z=5uUabjc7Rb$!w|;}y0i(LcsQ{|59s9|pGGd2eM06~4I5=!2l-Go4@JA-R!~^o1C9 zjvCwLgYEKQSw-r#&$vz(=UM{a>P^SWMzBY?Z4}xU`&@j#c$#BsZ|HSIyA=`4ks9$f zGf4@<|8%Y|9Q_<%?hIq~F}ngKtBFjZfB`DsFuV<=o0{_nSxM!2hu_|XxYaX>KQKE1 zd(ZZgO=ehDd{5jA+wF@uj0ca!V9Wh)`;zwi?%dqiS$Yt(3~v<=^QH^D#bkC7_7x}` zx91U4*MFHimz6g4PRtrkiL?3^e%nEHml*Yzfhc}wbbbqNCM`-B(}5c(#yil+XxzVb zQ!N%cxb=?g#rhkR^>~+(0&>7%fr?#o;(>wda9r7llOIS=3Rdl@!u2h$SyYIpsYde8 zl9?8#bfWNPL_o5VN{iLuT}(;0P|WD*?&d8ZHxva8=8T!;0gpv7xckn6Dm>c$`ws4R zd~$hGRit=o)2Od-;sO~4ev{$Sx43de2#k_q1<;k|L?4s)QjU(MY*@-y;JY6wV znT0gSxeM(%r0M#OtW5HYt!Py7Ck8`5s~^O+D1cPMS+IQt^0GM=rjYp9&-*Df!kiwp zTQGXN92qb)^aZq?+Vs!3a_Jpz2A}C8E@u&R6Th}=;IqwP;JZ+@zm$8pvMF6HQGG}u zVd@G4kq&X=6Qc3oys}#JB7$a+bzg?9YaaO!i{tz1e2p2ZDum#EI-5o{8hRMOkv;xX zc7n8M00%y_4_~iY4xPm<`LFD-_#ZAElpKorzIF_BEGV*nz(oec9&oc@Fz{WJd5j;( z`06PD0dsl=%Wk)M5{Ix4hnPN>Fl&Xq`Z$^Za!UKU>Eo<85>EHrPg9ccUl4KFANN0y zm}TbOliR9Yo@0Lm4qZo4cI@aX{)vPzfX|KuB`gj)Z4bg@U*cv)1M`P$W*6zJ3XM0k z;jWeIulgsjN;v$j0f0HLE_SWwaBH_}Z_>YSqG7bB=1+AkCR#oqMwa36)C|Z)8^8>| z@MYzA5L(EE{nNS@UwAODG_{%&e94k(E179sI(~NT)A|*3`=#0%Pe4XHURH~XqspTJ z)~>Lxj${!kHe?JmGI`e6y_Fm|KHh1BDz_@*LefYvv`!Qrd+eH=W zQhpQB$PN!NfC94DA6|c^x^>K;Nb-c#eDcC~r0?yp7#d86%8P;AH?gs} zneF)%c!0I_mUm-V?jU_pOJkflDA3`#!9(SJiwUOe_ffcLHW9yL#&^LMD{c|nY*)u8 zVev6EYKu`)Kp;KeJNeo7-cSsM8TO`la61vK=wwRA(2VumR>!g-K{` zaX5&9cx78NLAkS_vAgT?lPhkXp;xW>ajlq*SUI4_WT)Ni4N7q{0X z4*Z4!ZKsjMqpuzb!wxVTi>Yc6;|dIphfy7&-7HQzmSQ{8DOOtAm*gLk26A09;cb0R z8hFp7&rq9!qPn#0@;S?=w-d!$q>{9r|Jgo&=bHDzha&&c3Zjz{*R$9;B(7e)b~P{b zYeO2Yu_Yw43Ex=$iLXzm*=cR6!{|_AjwWO@W=X<>?%?CXLyJiMx9?uKG%Y!taZuJk zPe)0FKK#|3VUgFe8-?@QwHf;GRs7G3;YF!?=V=g z{VR!5T(@9C*+vG@)2D-uM0Twsex6-Jolt$Vv&nkU*mUA1ng1A8=0N^e_Tky7uDnL1 zqKFtWwwpX(6ZzVnCL-7!IpO*xNoS_f_ L9; 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

g8J009N^{CAf!(uJ{Qn`?-3Fn8H!F& zyh3XE`+Dhpt%2jg!8iDaE4tzD5g7s9wCI2&6dmAi5gqslACipXL;P<^O7S6w4v89k zs6&S&srXQj4oO<^p#dF|yy8Qnmmd8xeg^QN2_4dq(9h}7^5jpfC~|MUPe}{3selucbkuQS@ky3jY|zsHH)nVf1KW3O|ctL@QJH$0$a$G=)PH zBU+onA&L<#PWV~$Yx%anXx34TXiz;`o$znbpn8r5g$C85^(p))iV-bP;UA+I(V`R% zQH*F+3Wq30v@C_6MKSVE(vaVaV${)8p;7fZnkw{rbTm`wcj$FADD*q@e1j$HNa%Oy zbu=jSJM?;*DfBz^dKwh^9eTbjO@0=|sHd4izeKO6nL@ur&tK`tKSnX?X{zwRG$`~d z^?I5q^egpx8Wj4KderC%QiFb_-avywzfy0YnL@u(Z=gY;U#UmUmxZ52F&b#5(C^gq zXorjwO(*)DdIOCLk3`oLia>9mL7@orMw%%Ufu3AI@kl5Fz4h|MuM-r39}+Vg$R#hbTty zdwhsu1jEONC`NF6e29J#SUx^PF@oviLlh&pK0ZV-g6*S2^l!oT@ezs4A0MI^!TRwbiV?gYAEFq+{P7`*5!@di;@?Xb6^c&}7XbWS6eC;#&>{LJTmkSA ziV>~>_z=YiR{?y8Vub4eK14CXl>i^27_HX=esWQ`dU7?u3j>9#hid>nL@|=90RLUH zm%-}p)}OVYL%P!O5%nn)yg_8?D0+j)(oysVk)@;P4I)cN(HlgTj-oe+EFDE}5Lr5k z-XOAc6um)Y=_q;wwRH4bsi7lxG*Cn5kT3%^bOdSWP_QZd@{fTUI){`QsG)O683H;u zjX9*uKnE4Ajs$q|87K9sQVr8ajt`8mOUjNT-1sI)`)`sG)O6 zseu|ghol;)p>s&8ff_o8q#CH9b4aRz8ajuh8mOUjNUDJvI?`gGhR)%%QbXsk0&3_S z|Bq>=kZ=PvbPfqOP($aCasxGV4k2-b;U9(_|d z_c)XX12uFG<-tG=okMvrP($ZX9t_mbIg|$jHFORo!axn3Ly0g@L+4N;4Ajs$bY(M8 zL&xH&p>rrL25RUWN{fLSI)~C?poY$&v>2$Nb0{qaYUmtFi-8(Chtgu8hR&f2oq-xU zhw@^ehR&h97^tD+8KH*Gp)47wp>rrp25RUW%94Q^I)}1kpoY$&EE%Ywb0|v&YUmuw zl7SjJhq7d#hR&fh8K|LiC`|@x=y;h>L+4P^4Ajs$lr#f1bPgrWKnI{sG)NxhX!is9Lk}A8ajt^XrPA9p&S~hp>rsQMr!CB%At`OIy#|@)X+JUQX@5V z4yDvc4V^9u8oCZ;-$)Hzhq7;^hOR@| zH&R2_q3q-CECe+1hC)Va=sJ{rBQ(JB~siEu8)EKFu>(JyFsiET5SCSasACm4IP)*jMUI^ktzCTi%oB4?t8j!SYTYUsEoXQGCVi*hDv=(s9pqK1ykawcl%xG-m;hK?(9 zCXu1zBcYOj3w0)urK43~5?MN01tyWDqg7xMSvpz;CXuD1RbUcXI$8xLk)@+mU=mq6 zS_LMNrK43~qLz-vrG}2qY7;edT%be!(qL+FP0mCO9arT{)X;HR&O{9zm*q^<&~aJL zL=7F6G(&;Ub-h z8al4hnW&-TDxHZMI6xgZ>8d1h+pxZY=`hK}ofW@_lT-e;zUj_ZA9YUsG$XQqaZ>wRWw z=(yfzriPB|eP(LtxZY=`hK>t~^$YUsH9 zXQqaZ%YSBS=(zl6riPBoe`advxcq0PhK|dBW@_kYA(*M5<7%Lp8al29nyI1VYM_}K zI<5wqsiEU)pqUyvt_GT^q2p?xnHoB-2AZj%<7%Lp8al29nni|=kA&+nt__++mX21c zS!C&GrJ6;Sj#jE!Wa((7nnjk5R;pQK>1d^zMV5|Ms##>|Xr-D(mX21cnOZs?NT{Ks zGsa8}9oG%b)X;I=&`b>-7Y@zT&~f3=Obs0u4$aiiapBNR4ILK_&D79w;m}MC9TyJG z)X;I^&`b>-{SGrVbX-O>Q$xpPL^CyXTt+lgL&t?gGc|NvNimw&~aVSObs2^70uMpabeL+ z4ILL2&D79wVbM$t9TyhO)X;HZ(M$~;&4!s8IxaJssiEUCqnR2yE;E{`q2n^6nHoAS zGn%QP<1(X}8al2snyI1VI-{8yI<7OCsi7Otk~dRBM@z&^4INh<&D79w)zM519akOA z)X;I&(M$~;R~^mN&~eq#Obs1Z9nI9x4cGvwq2scng&I08J6forqjhVchK`Gn7Ha6Y z2x*~)j*E~MYUsEKX`zOWi;xy-=(q@Jp@xo&kQQp_xCn_JM}R9mu0mR z7nl9T*jq2m&z zg&I08QCg^>;}WHX8aggfTBxDpBvV7j6-x^>bX>8tP(#NROA9r0T(PuJL&p_M3pI3H zv9wS_#}!KpHFR9Dv`|CG6-x^>bX>8thzuPcQAbB7lSO3d=xnlxEFGOq7Llc+v&kZ| zbaXaZM3#=uCX2|@(b;4XSvoqKEFw!sXOl%_>F8{-P)o-@DSVj0tC1Qyu5DVVq2t=7 zg&I08Zd$0Jw#IX=;-m*ew{ zdO1GLsFmZhj5;~~hr%g`&oOG__!Ofqj?XY^;`juk9*)m1YT@|wq7IJFE^6TTC!p-?d3j|7rK`p`Fpa|{VYhr)VB3ell(rwU0#heEjyi9`>_2)>O} zqC+7lBoiG9zKwLELm?<66dej#LQ2u0H7fML5C1<`^hj7p+itGa#{4(4Ms)6DSpz=* z$l9WG`kBwluU?(rH^rCf`zxk6^d?!;e=-{uzsR3;%8a{%7j_Q6+OE!-PCI9J?HADd z;)`{Mn#b;a|Ln=@nd^Uj9oS;f=R=?4j_k|cGw009p}w_hY`r?@Wca>TKf3H_IiPp! zzkXXZ>(_t(eq_zQ-??Uf9(`oZu3g)wJ-T&c|3?q>wvc(pLHDY^+Uli zFY9$*vTNzY*QF!A4|o}N;nRj6%SM+=$Pv2!+Sg^l-zqHFTiWvR*qyxh-;HkhebnzY znzI)_&fZzB{^yR*5@z=sw7k`VRlT2l^I5Sc{&&Kw+Gk4Tn^|b-uecxI-gbQcV_nps z&haHj-`pDZIG33oni};_6wI*daQB*zzq}f?PTRRvfi?mA#}Bb2k4W)2)v0u|zBe#l zyFPTRP16;d62dpki`yR22z8ixcBkeR?%c`BCH`59|5Cj2n&S<8 zw~pxguKmrj|J{CleZjW~HD=ez)$wyLo$~*Eo_l4@*CKtFm0wqRZRV|k7mL?h zWBp5KQ_e}%dz7kE>CDep5BlvJ*d#3aeVq>{)8#A>et3KyZNaKFPk01}AD)*-TlCn8 z>P=htuPe1=!kmO#&mQy})MVnU83i`=5Ad1fnLbVKG$qoM8CA3P=_w^IerVrha1&4W z=cf1CbWyPzIxp(ta&pw7ZZ6M8EedmS9sTs7ODRk0OW7V&J-wyn;5iwqZ(M(_bgHfX z@nupS@sBT?>XLtaxxi&^Sbx}rc;CS`TZ~E^?U7+C7<7Wj|TbtK2Po*?%MEkrW&Uotc|^K zw&RHIg*>PDTfgNoEuY_akBj+MP1UVjp5@d9-v#H#oI7^w?ee!H#umz&5c9L>_2|XI zm!l{0H;6cNq0B||f3JJ5zcTu(M~!+L^qI?7NgkBNi+-7Y!mmM%bS0?h-`6tPtyS(d%gb_eJA?; zxtPdR-gUQlS1A!hzs${3yVTLU+UMI392`)2WsA-(?$fK)8|FlXGC zJ}U>me{go+uc-2cBQ;SYMh7lkS$VARWzPNfHCM-M3+tjkzwhgYei11PHPF;L?moZT zxiMLUFZx>Uk2~bOp1j4;?=J&t<}8zYZNRzCS;Sx7KkRh7QiC`1x|KZ_c4Wl-39Xhq zHH;O12?;M8JI#M%uVlX~>|E8R%aZt_t`ioEzH~BKW;EBtT%NM9=9?S7QCF`&)sL;c zMEs>$krm-33|q!5`W@$T<=)0CYrFY>%(Wonr7nF!SGGD77u_&-v06D-UwN}LreB8j z?w34vo2OO%(7tGNzdEDeb$W8WZeGLajF0M}J}hNBN4Fgl{4&R7^QVbzCkMaH(a6GO z^lVh@%9@L9rx!5Aqc4^(KhAAQ>Go)UU3d5rxn=jz3TdJaE$Uvn@1Sbg14GAn_gy&s z<(5)|=B)P^mAOsP6tb@ft(K8`nz z{yIKBgDJtzswxpy70y0OV6j7`6Rw!xzV#9>}tN#<-xwTKTP9)k9vE@_gC{u;j_+UxUi$; z`LA)~H;p{gtm5a(Rj#KAJp1%b+s$`w`bPWy%)NZ@p$}oRer33@FQonGdpCXO-6%9~ zU(HoZ;|HA>SmeluY6)MuN2M$<{@18;cYMF)4j6psX;|tLZ8=lT$GxgQ_R&2H?{ufN zWnt%jRq7P@cCR`B_l3$I>g z7_l;@TxL`B;nM|rzOQz(Ec~^`)rA$S1y8zJTi>ln^VJfs{)*2%Qc ztGwTUVP8_cJ@H{_x6CbWWSM5%e`E56h@E!^ws;+z@%hW1gEIAq%v!Z^Px__Gkd?*P zO-&iQCDo)Z7e;)lzh-{ZJvHd**92`p~!20|H0wnXvc%(-ITKU&>p0$Ij2z;6~t0|Lo2G`8;de^E&Ty zBFxV~bfBb!$%HedJX^_n^+w`C(*PB?S_X~~KB zOZo5_pE}Rvws{7QdvfAH^PQOkJD0lE)zr_@{8ih{0|y>za`NisqNOIDzt4XO4lU-N zvrNXdN8%p7z;<0Euw`h+>UF9I|Mx!s^yk|?#q^s{d-VLF*Y5{+``RL)Pl2#=$uCrE zaXn|xVg>eamSGh%EzhRhT_QT?kJ!_n264qbS4LjFS=4u8iU;B^w`)zjyE^j}liwRn zwe=Z0-rLjmLe$l3MSUi|yD$FIs>tXb-SS=;^Z9vL&i5N^u6t^Jx#lE59@Q} zQ$Td}r`m)H|6MuIIkz^;$a@19c*m_95%6wDF2983?VIlG)Oyk345?h*yU%%YcK-Ft z17d_WctTwrD z^P)Lo+Kd?H;TmB5%Q=0E{Zq5N3-WrGXWGvlt-SkL%C_D-_wxE>_p&{!vNC&AztA#u zj%Ux`dc**acU3~S4==L0&D7{s6$Xc%S#j$_WZ9d)f0VmDKj{1Imuu!L&w(3+x`BkEIz4jf8Cv<&&OGHKHs`$-h2GYojsmm zT~^%q^0?RaTCKYtyY*%5!riBR*1vxBZr6vJQIkS{C$AK+>z;AJ<6O(iOe-)F|H zUvJx>pY>lylrthm7XukY3S4@`? z>pXS_SpRaa?9DTKs(+pE>H?HMHb~iJ7Xn6)aur*Uv$t7rWgUQ{wzZO}1+L^G7|t>2qhirBFzgC;uI9 z8j|6%_HOl)^$t&+{`uXO;&YakoE$jj&8sXqUvGRfc6&^!w7DM~pOU;pVDTztQ})SR z;@#CYC)(ZHkpF&>g((Id^KKI4_A86mtQ5Vf8t;ytnPWp-yZ(WL+RyeY()w!g4x@VX z8e8g1lieG7Z*qyhQ_*wcShTl5!E<@ta{5fm>Grl=xh$LSJ~}b+_|T*MegDb+8(hBI5$Gl{i*+>addDeJYOc;yGqyY=QLaEpubmA3B(NV_b>s znbLI0U*e=Dy~nk&%c}RiaCO1-(JMB@6@Tq=`{b7s)&EUbVaL2ho2#DktLA&+d#W&x zy{Q6bZ8(tjc)QWN|IMuba;|F8Gxf4ncRTF8F;(`%#k}0l6z}_6LPen%=fp z)kZO6+|6kVlrFO*#etwysnVY?_`1~!Iv91pkp9O*zfSj#4XINgy*B^YmibprT3p#@ z%_QC4%1gW_r<%~9{g<;25ua&Y^(o`CwVpclZjnYOY78s5CTP;B$}j3q88Mly0Z-&ki; z!0nyKb7?#FIe5rllXHH=kJtSl#&9c}cxH-tvS(t@;un{nrCKq(dYv`zKi?@|YsQ)> zKVC)pMO@B1-?i`R0{v2SuG_!hg!he>)Ln4-QT?VqYtH%%T7B$&N@L+XWtTIo%xo-bCEnl``WzEkC&ckWxirlxV~0Np%~d8V^h zCS9wf+tM>K&8b0d`8h0C$XXMKZv1jAU2Y;{mGNRjpiuL-oDjRz@rE8wqZoW%B7p337p>UIbQiN;W z))nEdd)0sN{<&wT+Ubv{?bmg6I&=2;WZQk4-HN?7cugC9tK6rWn|1ubKc|YAAg@U((P2b(ORzw z`7L4p<#(^R?@Y~I$Njj%PdsZ@sd&(9^8j7ef1b}8{ltsAcDUt3uk%&nn!c^=S9Ol} z%S!$Y#&}K{8MN)GF6X3rXKJN;pR3!bOnI`WDe<)WW8>u9L51ta8@GEusM#rI<-FRx zhnLvhU}K)!`R=*KdGxxf(w>|tcuuT3A zqx0mA{U|8c#bsuN@~DYw z-6EeWPN>;!PhW9F-@655)t#04{`6F`EH?N1|!v9&laPP$m3$IMl7GM5P{&nTI?us4D4X-@A z)#AuXSI+dDb+}C7fvFx0m^A8Sx4s`dx>Rmxs{3kG^?V0LoH#gW(cKJFTMdiw?YZIZ z4D_EYIp_A}|C4sq)Wx2;9?Yn|e%`jr?x)wzsJh;zOjvl1T=!;F_o>={W`+z=k#S3B zF3CAJP48&*pBg{7J9$*I-EGguT?!f+x^hkP!h6!Bs^{jPI&9X5%{gwBbKBPE^wODa z63qVJFORBT;ed9>fq`p6&Y!*H5}ohGGsDzD^V2WOm$vsh!_-#UHjjT3lP$L9tMtDz zW`6tbq8%DpU#bK&O8gCNtyY7cUPrZMivj&b@5ON%be9%Ylg%a#ei{nB%4vOT8NFRe z%GhMzYjjiL4{v9?GQS=yEhzhHwD`AZ_!q}C__@OHj`-bKU$2f4uGUb6NXcO-lLmz! z9^%@;HIW41kQoy|1k(igYVhk4;slTyIY|Jzo%GiefNJy_{yi&=FS@Ulhy(20fpIZXTHJ#gjV%Al~Fa@qC!Vl4R13qm|dL)fqJS9XMF&TD?(&pZrQp zJGm(X+AR*$ZWkth!g|RsdmJyTdh1LJ>P?&mKRha4_T(NEocE|xRpPrc{C}PI_~xaC zf5$C>AncL{5mF7!YTG+;&qn1N?(n8vF(>azS+CIC>AncKyH9;2#Pa6-Y13(sN((j{=9~Nzh8qNB~B~>5GhLnaL9}aAcAQE z&`LuWL2&}ey;VqnDklN|uAv6Mrh$Gxx`&%s1|U?H4B(hqGhkILWI)ep@QVqe48X%J zkO5Ve0KUZ!SAX<4M4|~GkuoHJzXQ&g03ujO05KhL0>}+?NPsF!z7bAUxc0-qaF*Fq zFg&)U>MD?l&|_48eHHu}gF!un$)aAF1t|wx z)e0PJPebrz9?U=5uIlff1DJsRKtsU7)<9WUn16VOas3nSNBqGP0NU0$!U|9&19CJd4VC2_V4y)578naMK>ie837t%X z(nwhnz(9jAtVFohfL59<4Z9ABm>T-L20NY1M)P; zS1}b<0n9q&z-ZRsr=p=!ByvJ{US8EzAV-7JP+3+10}aBkfLTHYtQTEz1|)Sshti-l zOcwRZG$_~}&=9D%ry+PFLf!fQGY#5>%8~))>Y%{GM6tlb_A~@}86f{%>;O)tL20Bc31FZ>7#98%5@1Jz z@NN^F0;+rs*ilN7JA*QicTZ z*s~D4zy=9WWeLd9AY=eSWyt^o4Z^Te5=tZk&Za?Ws3ZgOG|0b`sjv!Q)*%Nx70~;J zA}53w6;)jYax^Fnm1Pw$&>##8G$>@ijt1e~Op*b|)&`|vvZ!aEL19>{TI>B`H2?NA z2(O~5JO45?C=Hb*1Ijcg7(dVu%)dPiS>L{;WdT)uP=*HWLS@N-G7kzoOcV<|OiV}Y z0TLcWj~V~{`tYCcloA{UYGaYl0E4iuU|3iHiO6>{3`!$qNdN;3!mx0W5fWergYZ_l zsvaN*gVIo0GQa?X!mw7wf(zQip!G$1>H&_1L20B63E-=lj2Hlf1xvslg<$IdRhNJq z3_=DVRF(`dz#t4O1))ST;A|L_hDtIZ4}<((7z(QZW*u^1(Q5G4L5Y+GVT%Y=SAiT1 zN<+mtFv>qT#+Nf0GXO9sWWWvvt-E3fM&MW&1oaRmi+Tna6ow@*2M0=e*q}60h6M1{OvbAqAQmLR zo`qn~CP;uPOF)hWAp;O9O9mKd5QdeKP$C&{HVsNcB^i*XL4Ff5g;fBvPI7>n!D#Tt zxQWmpzD}!d1adSe36ZJ2G+}IF<%My_g0SE(CljlU2P{ zt)SkX24VX(Rb4>lu|dJ1`Evm+QG5<4Wq^SOA+bcUkO6xdv~D@4@}*FY1|^{~Wq^SO zVOXMA$bdZ!!Zv%b1{_U;l1P~npiG0p$|8bk0_#)KCu$OP$K9YKXDrdl-<i@6Quyc6pfpmZ1SrFxFf72JkO1oySM+(%y0^1n0qVR+ zBm;xeP?<8o0E18iAWzK+HjoGnNnlWwCGck&q6x6h4O0S?aZsRPB3PhddlrB#yx|;B zr8+D_Lj;GDz(RaAlkqx0h7}e-BKmQeElA~4Ku$lb)ud!Vxily!1`^^78r+mJ5fZX) z)UI*{jL!vRW5@vBqWKHDFF;92*Uyi2??+xA!szA>JpG6AxWrA8DL;RVOXnT z!3N0HMr?wZt3($>D zla>Jn9)xudt3YSe;J#e;Jcu?KbU+5=cu*25%Xz@}JyKc&wgk)x8Ibaz7P z5-MYSEt6F};XzPu$AemHGbG9as+<9GJSb$q8Y5|qAp>?isD;LTs=|OA z4?+f#z=M1}lW`3I4?+g)cu)&HuOI`ez<>-7LIOynOiO@)2Vq#?K_LNFI-)eBg)U!^ z098%`IUbaR%9H^H9u$VPDi%!8jt8~Y#%9z8R9ONtJSd5jDFF;T2*Uyo!V*Y?hMdiV zl2Dm4z`%nrtds=oGXUM|;3RN34@yFX49N2!U(r->LYQ^Pf!?IS?VJ;#A!ykLIZ(w2 zt9*l+S=bz$62DgT@!P(M&7@5*}2=2xKx~4K+!7PV*&A`2+~g2jxLw z30SE^bS;3sjARKowmb;ap9CD_%bBd|t!gsTaf$|xUf1lLA7c?350}B!T)(fs!zby(nmV{uE#3ZDo9mgxL zT>xP+ECpeE^|tSipzGCNe~}Iqaue@80uU?~FaOM_fv;l9ix<`tx%J9fC*B?cISf>4 zU;pH4g2LomXN76uGe95=3lM14Z;ybeIidRcJ&0g%HqC7OR# zuKqFrD2bCvJ_7*4umFHWz7>YVzUOTGlLX47p8@}bVXcbE>2D8zoRjYjOX6gb&j5cg zEWn?2`V#>kXQQ7aP$vBh=m*2vVvoIkY1Ea(C-(%PRlS7ukuog+ zJ%Nt8_585odc6v}>}om^%`04!-Cf_C2d>jht5jT{5oM#`k00RhRV zL@x*W?Ey&IL_`(+G5`egF9sl`wXaNoFe>m5=(h(TX$uim3IH+yL?(&^$~67T{3ie~ z8CC$`MD$Al(82nFf5rM0%Km(*lFj-7|Agtc<3Btz>fh~`*)f{TKZ%rS{u%HOMkVwI z`t9)#ec-pzugdhx;Gb=vO!67%kBkcN2lDOV$05x_SY3mSGAXo+hC6O{EK$!xC zlYj`O39w>;cnL@-P!$uDD}zA>#2ln#g35J3frH7gl!NUv;A9X45Kc-07(h_St5vYD z1nfx=?T}$Zf~uSYG9)O8l<6E`KtULm2o@4x&qC7HA*!4Max5qbl_diVy+Z^SkfKl` z8IaJR!%KmX0Wl6D7m&w6z8SJS4hpjlInWw3di0=oA~?uzw?|<}B^=<;JzR|*_iNIa z&;}HuO>v~5@~c3hAi~f)L>LxuP{@FlIz-n3e#htW~WJ)Z62r zq;H5y^Z#cYl!nTb0c9K%h6Nmi4A|qKLwbkE;Gi^ArVJ?KpfD`pAY_1Cam8nVBW?=+ z83(12G9^G62ZdpYVBsVnTL+61;A9+>hRT!y1{{Pc08uPtz@CPry+a&KLo@+aZevP- zG7eH6whk-sa3Tqi;GlyGg8~kV^ecQG;7gf|8~`*39$?Qx(%vDCra@r^kWg7x07LT- zVOS{%C6WOr)1Wj|$bdWzGPDm7PJ74!XVe(cMly-eAivojWg(SlK!yfkfl7#2W=k9c zL-PvB4tVd z0}aBkK!ZX8tXEvI1vr}qC8089fPn^uVXcY<8?c8VY4Z?OmcXBDW5Vf5xRogZ3^WJ{ z02+cNkO&J%Xwcy_Bng!%1IpDwfrm*31Rl1}fV6ptDoa47ItV~4#zBP(0Ymo?VP#2C zD3Js>8wX(tNKi-~2l;l$3Lgq!*+UL=CXEHX_?rk0I=g>}U{T^6C=>@7`iBU^0uBlp zuu_NUTHwt7A<{5;6HrpmfP*mq!s>4k~4U0S6%ifP;_$dmMCf{}3SoBvPi6fB^>~0f2)-0_)Ap>?m$T_)z zh%{2BCBOiLa1sCz3JI{{5&cZaIlF;~kbxusA>R*~@g#t|#gG9zAmp6fK!hg1IyX#9 zfB^_$2>=j60usR?X9J-mRHh6t03i%3B?0>kIJ<#}um&U~APiALIays7I$y zA~fXe1|rf>`Bk7$BxPtIA|NoyfWfHIafucPIetSv(fwjos>Cup$cKvVWQ!MpQUa8> zlM(U?I4CRuD|Lvj1Ru@ z1I}(BBCG)k37|RiMFpVn5Z4Z_A>G?YM23g7?S}t`=ibQBKtx#fkOPxeV?r+=B!Yv^ zZXqHKm0tz&=W%S;Mn3AoSy8(F(Y5jly?CEhRLuLhV9i$ zN`sDUA_5>R7B7zhMusLLbn2~QbujhzDCq1qBGOQq7C!?D!m0ukgbdiDptBo^2pJHg zpwj8jfP#<#KtafWJqkLxm57i4F$yXrfB^*|0f2%+0<2&p`ZUNn8wDkyGMxkrC@2hT zRV>(mJqkLxortgm#3-n=1Q;rVkN`kISOSTFkh4)x5-QUYU_e0_R*FIP8E|$>5n&C8 zQ4p;Gq(BA*8Cr@6%N}xI)@gjvr@ur{P})?);rB^lfr@jWzyl0zMT86h3JMvpgCS{S z5zF7-X$L)^`G<~bpgsvS#L!xVswXrA>g{Pr+FV4P`ImW*LdbwMRNe)Y=3luqNMYDI ztN_D_WB{|3>XqR?XFverBqV?V2O+P3gRlhbaZrcRN|XRqmVn%gB$7~>mH-0|!mxmY zkO6xfly(?V<>r9QizJdrnG(Q&gD@=MppXEx(ro%{aMC6tsw@GSU1kKsBB3&6fB^@E z3|JNGAOrR|DD5<&$`X)ya!?W}Qvw)p5QYUDgajl4L(axQNvKR2V8B5bR*FLQ8IX1y zar7oD!bu=OA$c5R={n+T(wNbH>RP1Ph#s-wOh%0XZLf-Yd>BmVHmm4!A-{tky%uQE zeKR$7-Icso8&uU*t1+M&S8p%9S1oik>Wuy$=+(TXuUC67SD&i&eZ4wHxc2nIFS_`m zujsK3jouf%PKy<3&FIs7a5q={t!}PH^a3uDRLX?Dfl7v5UF*BnOQfF4(yIh#4ZUB6 ze}@TuUgj{Pp@$T4)^sMLP1bCyiT`_9GnqAJbl+StYsz<|(KAOHBig#yIx{*nRj7?M z8k%3k=pLkat=U!~wdjGhzrNON$@?#^GhgLoDN`y=7VC*=OQ~A)De!+MS*$0eGS*tJ z3g|fsg0&p94YbEvX$uu~uIRW&7h2$GuK8sy+AoS+z#vkV>lt5|Wvud(1PC8&5=j6? zMC#@0Y@jZ~_3*)lM9P!^Wvb=R8Ae;SEpq;EoinVKtW3d4aT$!1bjhf7A(MO<{)@KE z>NLveoRoEDi_ZUhSz}#m%DA0`wI=EBqEgnR{^aXWT4QM= z!;YGgJ~CSLSomM3Ctr=E!t)oGnlf#&w4Gt6O-bJwEqZwLe=1*$mjS-`Ezes?xC}@d z*8I;UjrGh_rgWS%3wox8|LBZ%>CtI%ZJYn-tVjFzi9Q2Ln%t;#5m4{ML^TGD4n1?P z^vRj8vH!i5W=r;JWlho?rzwxI3V2UA)kMQ&qMZAepH1J!!6p6PJK@keIA65 zLnKg^k3$R%bx;ENU!_9J9c9g8LUl;7LpcQQRm_^O(Bvzke6w+7hhnVlN!s_Q z1YGK6O&PdYy8YnGAgbx`mqDW!XF;bXB2QdE_C+0zMT?Bz8&gd6s_>S2>9U~e7pmzi zotZ5Cftb-j(jG{qi=cWrV?_s+mO?0LtS6?l=&r)!F7U7m-8AhlUIiG=%)eTAmvkXg zX_?VfS(En{6UO*ih;O;B?Ej2+#3Y@I{`a!RNT~cx2KlU6ufJO14jA0BFrZr(CiKBt zd>OFidUXg@<|S2v3gm{f01g^dbo#@4DSBl>2mPQI^b;Ny%eMt|#Or?@&~5Jris+n( zwFc?MBwe}kE_^s4A4ceh6T2sHjJ9yD&dnN`Cvf1?NfI8w;XAamt$i{&Og(ye-(Wx_ zB%XU)%vNdXOKv>a&p)I=tKpD^m6F-b+sOB4XOj0rEz&RTaiq$JQ)yY( zUOyixy1mMvpP|DMoccPV7xY{Iw3&Z?J5Wl%=<~y0Klkklw28>afilX+52LV6Kgb37 zXuninygiS2`fZ;eQD^zfoc?6O`3M>HD?bYY(+_$BvmVF?xgeihR>kTitY`fD>;8|dXH}jA)Z;71Y!gqEf^fLCjoTu-4lf?9X}enqG`$7Yy#-oKWJ@o1nB+Q=|Q*nwL1mSL!PXpAJ#og zw=n(opeJo#q{{TmfSz^wlfZcly^93-L@vm;{&ySB<9GR_oTtw9PIA9bbh#ty*)fl= z%(9*Opcd2v_K41XY1blECSL~gtn&G)VLZOyI-7pb3;M~GRV-h^c#f>+5$Q>Q zJlykF0drvLiBwPySADT`3FN6W^M8gsBA*1xLic%5ezg{rTa0qCY8^ zqfB|AS4*f?pj`efB%4aUvzrpZ#FI!_7640ABAv!$K@|X~=RrcOR|6Z)Lyw@?JZz&5 z>7cU=y$FULNYj{5*-pfHF#qhJ$I_38$OpL~AIL{^{!9B2sdE0yfF9A$N6JQeEZvBR ze$Wg0fqlgKZAs73^*ka!38;syl+pb`F37iG9%~~aih7Q&=Mm-1tjE_M*=%15Jhr+e ztf$TcEO^@@4JAJN6Fy0>$M;j0*A8=EHf zfIYql$#&+0UeFI0f2v<6Z8_v%)&cqKti#Z4h#wSJbjfA}ARj-=s70-(#quSnr^=QA z)byx=+%!2@KtaAO$evLJI6|-|D2@h8&H1Bn3&pJ%(OGpdWA#^aKBhmw9$Vc`#yz4tNw~+*TnOeE zv|FE@)Oi8^h?l&RagPtxXj9u$*glePmoC5NK|kmP{UqID`A)<=B3+DoO45~a52VA& zLZ_4kJ)H^oBbM%D+#~Wypgis=$ydfbkPmuc<^g}i`kjn>M86pKl=Lgt_5}T;mI?ad z;xE!KZ7Aem+ynU{+*6Rx&`Sv9gItgg*M6~l3GO+Xb%=g3>nQ2R5wjT|;I5#bY|JUv zFL_i?mAhIpH+6`9h?M30=c|#72_SF_2>|*LC&0O|2l_>@r!@b{wLMt>AQ$A@K##SF zkn>=VD5tQeq+9t-ZO|=qGwXKhTdzzqDPDgJBQki(pS)zKNkz z5Xc9)AU_e9`CC^|zxFX#vQ5$Tt<`f)JqfqZt@W9ae&@8H@txGIYa%MJ`OfmO~q1a*0*; z_?_xhCw)m{GZE?Agv#`OhKcV|F24d`RDt$L0_Bw07@AjqE?)$hC=-QNQw?To@Jff_@wJvG#JI?4!zO z9huEX#6dDyKSNg*7*l%Pw-qjdK1aWoWD_L4;u8o={JAyUvO)2>M|@ro&!H9&s5}A; zAYS!+jn4~q7gVXdDFZ#?P)Q0DsE?sjiuDagbQTfJwfdh9?LLM&wA$>btV3OHZR)$K zoc4ddt7DB+2$USkZLnzKdy&gu_XO-G`UUJyM87TdIr_Q>)GzLNqBQ>u;73*!EO;$B z0qmg{&y1+N@6hL0z>LK;P9^O)T=}_&Q2~01bYMX7x$g+(lex7ajT9F-mGmnY`CwEK z40E3d^zs|msr`vh4tjyd(d8NKpw99D6GKxGAprorWCZ{OidF!>cbzB!4mUsYflLIw z3JZXtK?vvvy|4g)0mb?y%;#|EB@2KLm2m+uKpzufieSA+H_m_cQaiom; zl?#5b06;J3w_!hP*A6E_FOiOeWIOZ!-?`6Lxa6*`!=aZ5CzK1OCl9?WT{MWz3D8US zApiytuX+jdsdC!Oyr2aOQk(*X2RK>UXpjVeVAzPk9(wqV?5OQK7J6)=Wcs+r7bfMQ zM*v;|xDL=_RCS9I8@^O3THn{Ck+@CsE@1wpdir-kap5=H1&xiWz>(0lkyG#o(g(l z0RRMv^*fvTNCL#vr?dbVsE>>af*}DwLE;2Bnfk<$GA;lH>La6qUeIp?Kayq|>g+lw zSLzf6$#m^w>83%(l!A|~aA#AWI7rq~Cqp|8m}Nn{-l)-|zEc1};#Kc#>LZSv1nT39 zlM22k!CWm#fIao`JK8ym`fQ?PTloxSJ~Apm50MTGAf9{MGM`FiZkhYLl1Le#hp$Y^ z&poAHE9DB*Yu8jm=j5gu0`yt~g%5rFhu=Tk=U`~60Vh99IIR6dpikOV!{N|J762bA z+cl4&t%i^QfIe~t00fE707+X7bt*l0&Hmy3Hs}|X`V^RlFHXvz0H7cA!U6yW66<$1 z^pON40s0tPYd``(FeCsVNSpvCLm$!4N6L5tFhCy}74(9B8}^Yj*Kj=aiGpOh^f9#8 zfQgrKkF9WLLmv??As%x02j6FCumQ6yh$pp_M4*q~(vCupN*8{a``g5kB`J`*@G*4Q zfCPYGxUX#weP-L+yN)gO5$)C}*;YOS^pQ~k`pDb^1Be~Z+0ZA6lmYq}dThYlgJ78Z z#GuC!r9Qbz7fC=;phx)zuRy(oas}!oZX;R&&Tg^+*eh=QbC&0F7diGpOh_AxZtfQgrakF9WLQy&p7K^}7W2kK+!v;ng$ zh&P%w7E_|7K7MaIXHp+=WJwC-sE?u51|&eBK9T@?>a#eL`fOmFZRImi9~l*>k4Ogy z5<8x=sZSCq1NEUrtY~>;R1mC%1P}%gC&1a%Ck~bElRiVY4OskuxsU*W0Ga^3wA+TG zp$GJ{Lk~l{4S{+|6N^7nuijSzeU5&@2dG!vZUa%T`~`ra-3BZHm~vPGfI;FV;B4+A zYaj{S$Ix#B5&(iB0l-1x1UQ-di2fvSA49_p&<}b+zZie`W`ABmPJFPBNarv1EYI^Z zbld>pQuMJE?riQO!X?n7aN6Ub6^i`iQYVP#H|du+mCk~a~<(A_<7V+0Du6|3Xrzla5VRUes=C-=(_KdtZ@>zG8HW`B6eLc7lc|p^fFw|#g`wIQhPp1NFhEL@*=(C`hydr2RJ>O?~1>ne>|(8gRhL4|+jAFo0OUv#F0HKumq| z3&6}5C>5@KWK<9g2>=KXCqP1dsw@DRcUZ-dGA;ldvAlkPdPxfoO1;*7fW`W4q0gZo z`hj>!lnlgcW@y0ys~;vCCf^2pBrP}`PkdzFagZ$6Ju}}4Sbo+)xDu4iaEbedv@BZ&c{;ySp}_GG6qQsZSUcsE;H7C`hyd zq#ZdNOno+yvgv1N$pNE+URVGCL1O(*raqfc854j*mallgs2~^;02CxnfODzOCQ?TI z%G3v=f?m*XbM2Qj<#0IliGyUaeul0bFsAgnZ!6r%8#LPlNw4_w(8JJ{LqJ}FxB~Lp zwdK$|yDbMGuedFT0`oJp<$z@_%syw(=um+aAV_@LJGs_p6DnN;{3oD4U@t>k4j2^# zb0h)w)aT5$9JW!io%+gmcVSeZJ|Z0;NIdt>raoI1XQ4iZwj7`z1jF3JBW~gZIGg$a zNYQeK+Z;+~KLho_s6c&W1poz!65!;v9KuxLNZBs>3~f1JRL~0x03b-L-`UhB26Dy( zFi;;E6$C>9fP%yca5D9YBW2XjKz(FX&SJij0kbTK*BLbiW1^)le&;)9mb!=|OH#lug+D+KLt733dkN+W*h}6V z5uf%F>T~d?eV|@(TMC8i9z$CWSO5a_kp*B6eW=y0xZ2~;XF6=7WP(1vGO6%E-xhE= zA{`h=JoV0oKHEs)^p{=x45dCYDhL)5U|;IvcfM2mSusHGAif={Wk3Lf5d$WJXGKNe+!kh>=hNFMGRw^F;dw>gbJBLAWzyH_I$CSIC``qXKJkL4jea~GU zDDf;5`t$epDsU31wL{bNk;W#`HT_e0&t%~9P5Q{*nZkI;tN-9U;;_=QfG0O|BDyu{oa2|ddO}< zv_wUE(4^!by#xxiAY_7zwEb`%I^;XJl+K^b_~z#R-b^p=A@8dKO;J_-*@ybZ89#U_ zUJ@fI0e#-`ZwB};Xx|J50Fim|1V>m^PQIi7~p@Py(sc>j7tTymmC3r22w=8Jm=+@q$xVq0}TnI?f(E? z5CDJ$QsSS&`b7WZ_m_bI{s-C%Ws*m0000;m0MI~615AFCV{Wc{{{1Ek!2dtcUeXvP zIsydn0{oNM-+brg0MJp>UKDvbfXu1PZ!++Ceynejk`s3~XQsU<@^Sz#kAs&WV6cB9 zy`=BnO_091;XN}w)JJZQDM{}vudkuV$^qbylU@@1>6CXqb8<}95uv=ZA)lS`0jYrS zkbr~UpR%p{FX-M(bZ7Eq2#M~@hJJRsH^Fxifj!BA=$<8e9Cyh$Z($@ic56B(~KA=7n(Lc}GIL6UajBw6|9tG8# zLTwS}1KvZ4e!htwrJ^XEkAmotr2@bRd_a3B;mDQoe*^b_j~!~5F-Xcm5r~*OS<(vc)E42k zbf%@$5!Hw$DKGFWJsioFfZUN`gWjIf=Tqq2-1z+8Z)zdf$$Fw8Hz+c1ATj}1;PbzX zWRX5=M{!LvC*Wtgfs3#%s3}JI%pUX*%51|J`;cV~XWM<*aEiKJ0 ztmsbMsZBH`T9DS@N(?us@SX7O+mZjY&O|2*Q(IaQ%)ehxrqC1JARda08;DGR6+}KD zIuzBO^f|i;>~r&`!VH7>6pEq*kAl~cY7+npzyqE`34SuKn;XZ^Fnl+mCra!nSRF|w zzzVQWqBm3WY|O=7JJ7#PB-WkQ%fTw5>f=yk*+7D5DzTXidJ3l#or^jy34i7TGclb8 zdJ3f>ul|G4p~$cS{5uX^5{rQzNB}H{GSsI~x;eo=6Qv_Jzf&wgih_UPhgF`1+>oUL zz@iBL>8x%(^J@SnAxff)c@)ETWaxm|A;McL%d&hEzX1A2q_AN2SW{+F2NLG;K{0bVkEO41`i`heYhKAT9PBdUH6MP>~U_ERX&WZYB8 z-hZ7>XOfO+@6k%aO3y-fkVbwSIzbd834NFtupi2hpF;QM@#{Hs_5;t;`h5!TPtB(> zC&QRC3}jI#O77=oL60Jx2HE)lEpR^Q^(oQAV|5fmS#uKmGYw@S@F`i&Z17=?XKwPx zM{UXUksyM>ib5Z$nx0HU0{dUkycybjMAiQ#nT8~aWEy1u1Ahbm1KLCB|0y(YPNIK? z(LBWcBt=n1KMIzI2nA>X`blhON+ylD8O59!$wS8WD2KKtbVNwrY*CNm9SlU|RH8E( z_7svQ_J7~WQ;y{!%hO?#uj4>hM_&EMkQRzG8oJM@ti3>La%0j!5I;HQwhxf$7+ z;q?=8Pef^gS#H~)NTUG^00096Os9GCnMPx>mZ&anNMn#QxAs6P87qJem=C4zrx3ll z@%;=$Z!-BtGpa{`RYr#&03J60nfp*0U<%cn69ddd^(aX=x~qE9NF+)FkO2b&0Qy5= zfO$@%0Ya6;!cpNTph%+uqyoGEKj{7`@lT<9a}oeE(LG8Yj?w_L^F3ey02mkmFaSye zOyPTT!gpujJ7oNnglFc~pCB^(sNOi=B`2tu;Je5dd@1oy=6iE-9~1J|-=EY0To-*B z4FZZZ8o>F$*}(aec+Y&N(V$ckO}|G#kwyc^oJx8o1D`_p{_{~ia==faJLJ{BGd==} zG#bFmO9g<%$Of3s`sOo@25=LiC93Nk6lpYoRKWVk z&;bde^!_j;YX2114spU0e&bhrm{ZLhwA3K@0($qZ<4Ag4S<66k!t_|3=9BR z5M=<&GwY+&6eWHXtdA@e;05?6_5JgmMgzDWRuWayk0Ol*kU6#ApA3ASzpXb(Nt6$; z5m2Pj7^l2siaSnur=`)5nC~!YCqqsk4#D^ zS>Mce_6aD`XaEBMz+z+rOlN)bnMPx>mZ&cHNJEpebo!GSE`Sb55T)6r@dsFJ5GD2rO}WeeX5S)YIjZ^>iG8~ z+<^6>PoqIVkwybp6*yds901cv-+ZRgn5-o#(uX3A29OGd`pD1$2cnGq`6hj2HbObn zH(SexVyKTS6#xdl2P0pU2AFTsN2w~xJ`V-y15yF$BS!!rK@JZWL)W#tAQ(;7$-;cw-&HBhKGNlP-8SX%lMgtfC02U(~U^?rYl1Jk|eSK-NmZ*lhP~^}6 zQUU29L;nlunUY0gj&g|n`+3$WnxeVCNgA1)ne-vt32H&f$>NZ{4@w?4EtiA@=?ixh zq-Re0{C~f@M`n3IQ8c6v9y3Ne%uU8W&iem?f67qbe~f>e^dpxesPLoUeB>4d1U#tw ze<8i|olOH&07}w3OXG(ko5r|QKzhk703d-Bt^Yjd)0m_wne)ts9|h+l2LQke0swG8 zO8iqe-+z7C3k*O~6{P`CkUp{j0AOGMKmsWZF!}A>|N5hR06$4nl=x?Vr2|L>cme)N zq<6lvYEUYPs_RFQRRhQ*ktvw;l575C;3UR3kt+GWet~zAk`p&~Nji)E>m5cEc{Kpo zaqyC27!l|#0Kfq$qkg_0>LdGwj2TVGha$HIFaQ87MmE57(mOS~hUEYKXdl!}|NWi) z$y%Zs>O_%W14sp=mkb?n07~D__x)Y6@5!2?^8M_j58wxYf$#rDdZv)RIqCCe8tEe& zfRgmga=nit&&K#zH<{&*v)<{SBA)L&8-Vtr&$B^5k!NE(0s!kHR{_9+D5}7eOdE64 z>HqubmPwkDJN;P#07b41AQj*RH2{zxO8oQ9`p7kalJ(7I02Hi`EENC-1^_IG(g5?! z`Y1I;82~6)A6Y8E3-C`OKU1=9%uS+|8NSj7q7+sVRo{mq?*@=LmH12sKHsd5?42o; zhrIfahx$VRMoEJh5Xcz^jg z>68QR2%*k1G9gZdE5ZtJ5b{WKwgxmZ22a$zyEZ& z7k~#^q5(fU^P2!q{we?fKmGd!|49yx8E$fq8-T1S8UxHe-ZyRl@QxTTz_hp7a8r|T z{MXbM7yxLB!T>0;aEu!OJT43jFzvZ!+|(=_b28xjZ{`Q^14Yr`pMAV<96xw?WE?*- zt~^owaimY*Q4ILcNdV07m{*knZ^NdNG^^!ezRc){ztyt2b!X}`bUwCV>|%BB_#-e zzZl@ZxZgX20YC%*P0>UEtn&XS1^SBt=9vWo15BYnGZSGHX*tF#{kULJ3=X>IKb-~Q zrX=Qo9{QbwOq(-&qJFxnv(rG*kmbxlFfMkSU;zste1ozdm_h^RAlK+W2SBH*i30uX zJa9rRf)5wb6AR2R20C5U z*)4z~OUJm_ae_s*z;q^vg?SYP5tth$1cfa|9PV>5c<7-*A#^TW~YMVV#f&< zFaSb0D4Kw&c{=7K1ZJRu(^W-bf!Vp>gjhha$QGE+1xX*ro9htxHy50)DGCFiAcKJW zj57?f0j5&{BxT108Jv?4n1Kt8TVPyO6c&IVS)8RGBylQ;4wIR{40M?Eg*=K7_^*e= z039CZEQkSSCPOIFcZ^$hT=2hxUgqOt+3^=x54#tdvADuy9I z_rw1}2&bg*`0oiJ;3_~>ID%(+5C}yck8uhF2;sN|rV&Eyd=f%{9;k^1JqkiNE|yFP z0s85Lko2iMie_L=8p0U{1}7XvRuzo}P!K|30YC_W1*Q|iscAgs!~!!B!l|mxZUL+a zicB8kmIaIum|!|16rE>A2rK|JMP&gLln}@TlyKYv2tlHtgz$X}N=`f{K`;{~oT@4+ z6QJOP<8l$mSYU$boRIYCJc^b;bWVChsOnSJyq zV1{wRsj8wf0SaCSd3&-V>c_A>tbY6&L{+M7z|1~e1swpZ9 zpx}i-F5rd00^~VGUobWK$DFhTGYu9_RTY&9Q1C(^7j&~Tm|(tn;Z#-0CYXg6qDTV* zo)iE>rdV+tMjZOU#$RX==|g)Iyl_t9U?y4w`~&=jDh?=Vk&cIh1-G!q!6Vv4TW(<` zD;uJP6EwFmC0Zz0nAw{{JC&@QoQd27==n=wH48gS;$i4n3WyB|@8*Um7Wek;w9Z5) z3sYNK_cx#QjO<_Pukaeqyc?Ft_VL#!56{)Bnz?k>*i23NOZ`;Tts~woX2)TBUtxPoj*>Mg{RDJlf1pOYE<)?mL)$_9jeZaJMJ+p4eis)3CWg!Bp2ZWDU zTktVj`|C!psDJc+(Y}pouBT=0oidIvNLFLVX2k+vU8=q z50-6=!=C<{#k=0up?<~E+!HxLOz#|`SFCvMp%S=&v2U4=Q^A9aOC6}{x#)-y63gEO zrV%z79jsa`$!r}eENsvpZgQ(D{Lz+rX#xE-LU6l;_1ZIEPfF}8c$?K#OJi@~O!YNd zV&{GL@{3n2i_EHOB^nF-WlZl`R@D-=XLZ$W^^w>){Nu?*zvi9wTx&X5tV5f)4V=Zb z!qW%}G{F)(IjI#dZaKI4@Cz>W#UbM5_3RI2`ja(sJY8?EFb>w$J2diJzr+6GP`19s z$V0U!##chLehKa%tVxcGTT2(!8FHbg$+}rMG~~;c%SW1v3iAaN$KD_N<5bJBZAo-l zJa^SAsV6y>e^hL04JtmXNH2LEAbDBW?@gpTeKy^#s{$9c1(kCbu1NL2pSAJZO7mp4 zV?UeR%05Dyc7|aZ-O9|uTlUhQZaG#aA8r)bOWiSSn~Z&eDRozFPe%?g`ut6^;n$ZB zF5&Bfx)t@-;#`Ekm!(Fw8drK>xTAaPsHpv3%ksYL--`Eas&D?>-?8rI(YmPgou*zT>oHQBH^7cC-DNb&HwYuGqJ);$>(h26BBbJhQwq`4Y#khc3Ct z4dY*qxvZ@pZ2$21*eSDzKh%XsL^3?hMzzzk@(be~y^S2}4u*_vu73QuB6zGqqapBS zXz@Z7mqUGlt3#K{SE^TqeJEBa8*!)#II6ur`hD%k_tzED*M_+e2<{g;y@_QWgt%g> z57+Tw&x+j-3{Z#mZ=lyYv@`kna*d`B!narEvyQxXy|lsj%@?t+2KgRha^;68tiU58>jJ=Sf*se*4@%oD{=|ndaEVj9kKfO@3rs6GJ`Lj zq&Zb)ai@SO?C$!tndLWiRqo`t>eHRMb+qY{ZpVQE+tD7&EHBPY1JP!_MaZyD|Pd}`1|T@?2h%Gn6la-nzS*Cu|# zT<^J!iH@npH7mTw&ajCeYTBw&7Mcb%5Cc{FWsgvD$~SJf5z$Igp*b@ndwl z4d!)DtgW&YK2|l|4(Cb#v9`;r)UKN+Zd5YYZqdravIj5UOtAm)Fj67tG55*xCmZ%F zYRC5IJ$b$A%ji&h-;aD{ZnIT1^hU8%qOLn`wx2TM3)iYu5Kg=qqcl;1 zB%bbUy56CnR4cmopkftGmEV@fJYJduI*u7BeJ8i*YV>`qp{mQ*8d7si{!A$IE9jO} zY;~8_puO}&dG*e#8Un^oVu+#3jfurY_WM{g+hVIZL~-$EgagFla4lkJ`{TrZU1rtp zl`B-cIXUWkxK@|+cpfu;zagv9L8^5#6R~)sfK=-)-d?V@2x4&rwwEgm+glWVtEcFv zv21te=%2%jtb>#K<&bzk z=S`WzzdC<@HvVRmA#9)5FkJrm^VrY!b|-W zouKV<)zuDtFY&d{o+~a|^-S5M_Kpg-*>Eah`zKzX)4>~#F3?r?r&Y4{&O4d!qU63j zmqy%hIjt@ni6%SvxF2wYQ7>-eqkUz!s66|V!!C1k2_Np*+Eu-u(`Xv+D3%4CRxe*! zY^%E4oK?t-Z*N^(jdahd*a6vE?XsxrKKXkF2Z|ZhW#Tz4p0m2WNzj(QaSWp~aAxt* zJwFtbUP$tK?HQ4KeAQXnvv%Zrv6Z?^fW4G46x*R~?zJOu@Z@s(RqLs2iZ}Dolxn@3 zrPN)sQmMP?7c<`H;mMaHyMq$@w`tXm9AH-IUKVz>|IBHXZuc`P-2tZ+yI=jGl@jjz zvy)||HfubGXmItdZ(PI!bZqfvDLPV_a<8h_$VGBgpGrE?EyCaHFg8HUKOS`{&$w^+ z*TSM@DQZ5s4wq+r_j8R#4y0 zs#?Bo-Od-0+xF>;g+=4e-Y+S#Wq;}E%KofCgT3kJ9(w~K?pTh#jcXn~?pR)Pzb~&y zSXJo5Yh9*ducU1yB!mt9BE6biCC-1Y=z5zLSJjfv9=o-8Uw6;i{k%>2%a#wCy)LFU zG0|Y6({()F9m11TnG>;0y6attLw_6J-2m(briU$&?|$SfaGP1_nDo5i4Zk(A(ubo^ zf&0o?s^y8n3I&5WWfQ9wPBBsUEWVoN!jP3Wt_NBf#fJKy(64;(ZIGTR;7E6??I6<| zZc(KO8O=)-r^8zao7|_-6t`H}}EIXYFlPq_X*(=4lTsB{I{k(ysm%uv~2K*Xt1{f*YNR z!*6wRonqndrd!3|t#5}T7+dr@g)Z!MDt0t2jFUHWCA2==rM75kEKm0_{p)dkL8{fm z*<4PcU%8y12Cci^=XN3fFQ94G7!NeMhr`pu}*#UqFYL zutG{I-qKlzSiOGjUGekD$hixPK_+C^!Q*oe^h>56Z$q8sLXZ1O~idTe)VS1wP z`8jC0b%@O4FMRF`jz#v^)do{Vv%ih0ja<5GQ56#=Nt1!8gjb%5s>6IqsPJ}ci zi<*KDx(l1vZSYB48NVuucs-rhOx2OctOCopBbtvxG*_@)`QR>RS?5SgLD5)+<$1&l zOQJEa)_bf`mN7bM9+s{4dTmMeuHl#)9h{t%XTSQKKI^E^75+WwG*7pC$GQFsMOJ)? zyyxRI%moSMZ5`45L8pbf^)Z;7K-;@1d?E`P!b=|oFc3~DHLp69*1^BQ$1lKu$-<~% zY2NCnxJ)Zay+hnw$$X1e$ya|1Hi~F`65~`n0)=AyZ}0F2*vs-%qPcNqZLc~!HFTUp zwK|=O@d8r9%hD73kAwzSKQ!Qv+p*0k!}xRe=Z0USPNPGaKkORL=QVx&)js6vJ^IZt zzt~gyi|gq3prGQ{<&RK98WvcqjKX8eKiSk7JiwPKZ!$qv8Ad zDydREe5$HDK2_yYQKCcT$3tcB4)&j;$B}ww>mhSe&%Cwp^~rOtIVp7?4wabchvEA8 zU5^RN#gFP!QpA#tLCj}r{o5rDv1DAL+xaT&6aDbm&kaXCG0ac&l@`f2Z16eVlKJvm zIkbM`a1x$G5wWokUa0M~^dEkV^Eo8OkJaK2Vs&1>aAC33;wDR^W4>fTe~D#P&PADU z3*zGe*Ltc?Z<5}_9dn~+(>dt~t=p%CZY6a=6fxnJ@;cUdfs9K{<~MFg-3yav(d<@w zO(=`c6@wU}^W`La&qNJc4RbY!A#RKkHs_0PZwskDKdfTCNWk+Y)Kgz~wh85k7dB^& zH_ONNct-iZAT05JG4j|)Lh96G5vkUdwExwQc;d&9KwUO0$(X-Xx zR+D??Jm2bPzmALh*pe9{`}U>r4RVUzD+8V>Bx&C1_t$LpZHa<<<{+WR235~qzU=&| zd;IP3d#%C^_J4x=oV+{=?-lQ`vmb6)x9D}xq6Egl{19A9PZz5761bDZp zovW#{v(-^}Ck}d79NH#l?_y^TiIlTcpSV_*=mo4^YjuJ2@&Wk zaudZA?9E(kE$oPzPWEON&d&1oHug@=Qrz+$rgq%wrk2niQ*Hwb8ykB!ZaEuMGiwG2 zyM!?`2xkGov^6DiL-)QRi^!^AMUCZLtZdA8yVxGIfDC|>6oog78IwfnIzzG`v9Ne} zGu~Lm7TTh1K_o%|pcBGY-Lq4UQVnP$>E9;9JrI}3Q1 zgt4p>Q5$iYxHvQriG`=go;@x$7EZc$RzygDEWC+;7)l))&$JsG6j5_ z2oeKN5ivTZPL>u#$kX;VE<{ooN`f;$j!-l8fTDB!1R4$&b~^TZNjeH)#U(K~9CU+P z5{HG%2R)2{h3tV9gJKRZDalQGoInIx`-rg3DV`qlHwF8tKo!kzHi$G6oPK*rypVTH8sLo-i0@#^a z!A^u-4pmAhPWa`Z5VnKrwkZ^@1Sm9>E!?@~Jct&~4E&JsMa0D5DGqw$S44zBfT!~E zV5=DPgO}mGVq)-KF)?JXk`jD0auf~+mx4SBmBQiRQaBu33Wrlt0x}5%xD0^+mmxqu z_-FzFE=3@~rQjua3YU_XhfB%J!;<8oA3TN2C@H~vm6UK$)q>~nekCR37(`=4Uqm0| zjL2U2NcdQIDh4%C@DwfuV}hq}DKRm)6nti|4@Lwp!)0JZ@D#=kEP)&gV}iH9YcL{s z3QL0Z29jY!@G^`Wp2MYJOz=73Qiy&qGI$x5gy2$wey~QcE#Yzu{O}yHG-6A{R>+a? z9vBBaMRZ4WL(UFsjvR^XgQv(3E(PO*r?4c%g9vJ5AL2214_pey2Rw{e1vwVR2XBYh zV04K8;VGgyyair^OTqZyDdI&q3SfNT%t(xY7=Sg0wSl+7_<&~c61)tb7qJ^`9auWN z2R;`(g>4Sc5$)jf!Dm5^gr{%`@Po_1=s;w`=-{If)W}{KAG`%Fg~T_E53vbyEIftF zz~~tGL1ZJ*0Q(5uf}8=CH4($`*f z!&)H7;q$?Nh+gmjymjtIC6j0i*r;xTv)IVW5S_82^cOTmcXDPn6xBe=|jCE;^VSOe$^ zmxO=dyznyOBYAl&)Lz0rc#gD+Sn^L)6xlN|hZ4a-Ke#)Ee-m?Y(vN{3%9lX;P0S@o zKRh1UJ~79Wev(kP3IE_Za&AfTPgWM$GclJX{p943?Gtl3(vN{(K>^t_F;^h{6cv%} z6LUq<57`P&VSmF@WEr*%vIK8K){r@bPgGo9TtZ0!C$6LS;5|XgK;)+U2 zlHwwYB8mhhIazrT=-m{&D0GC9Jd_<-6fcQW!b{*qNJl^z8TeuSfNqePBxLdO1X--4 zn1qrno**YLCMzmSfc_+9v5;osu#WIQ$Q}?H7&l~ZQCM4eNkRhA8{S7+hXBA4xN*<1@Rzx zA88Au7xaTQhnJ8wWDeG$xq>L^Ebx*D2?J6NIUDS6SO%gGydRbYmmpyUd!RY25vdf# zHW)XeGeC)011?KCGf6AtI1(bV9B4+yjg*8-An^q+L5?FwFN_?Ph*$uWK{T1L8hqr` zKSTHIyV9!UC5^rhl0$h(jKQ;vBLN6x&#M znS>iFi-p#qR!1I+4d`gnIu!75Sx6e>9eG%D38?--^%sd7(iW&?g8L??alsJSDmW73DsFI|ZEEIQ23UKd)L>jR2ln8+0 z1n~?qhognE{ew$`h@&itl))>CDv2sW?JUVUu%@7vP|76vPeGJae$S)!an_J_Oz(2+a|*AwVR#t0#T&jg>FybYSeI7#P+ zdKyuv@t1|pL@qB6dl;5UvMK2p_-Im{Cml($9CSS8e%NMUi@dCyyrew2F2IooUDP6H zgbpXgj~EnZ@DcEtNbSEU9Ce6B&=yEG+}FWd;D~167bis+sl_JM3zC;0Nu=XpO`!e` zE{&8IAMbTUpvZ;#P`J)P`|$FzB5)LoLHprtShy}Bu`MnOX#nqo%fV-cm*Khz#~LXr z$bA{2Kh$SJ`p-UvaHA;ouQLDT(J(iF(ZXW`@OAfJ#|0?wn2;YVGo1WrnbG)D3(yl~ z&}U62MhujLn)Qx3H{E6G<9O#LlN=ek?F{vHg&^YC*>x2oM+{f1>~@Cf`bmvkLW#Mm`?S#s`+geeqbsX<+}BOI4MYXE@?| z5=-^7qVV9`Vs909XPPZO?7&seoyi@n{tLb~36wa0ENwRX#Iek|TY z368XkYRW!bdil-{@9*aLo&ENsNUe)?e-qt)#i2v{UWahqrV4naAMq*TME_@OP-~(zV}>?!Wwa3iCl~G_>2N z|98Sd4Xd+`lA@nYpAT)_{#|agaFw2NmfDq}xC4ze%{8(QQdrzgPaMr?a{TEU_{dH} zyE3|}t;Sl(eyBEIIpy0+8Fm&H`j!maSmPW~3?YhRvv#p7>t^v#DHd!en@XSe^Pr)y zF=yQUB_jMzDs+K751+{`b=TZ=!cUUlS^&T3|$pZjXDvtlDMM>$BH>Eqvqb<=niEF9e_5 z;-+PC{I*bh;^4aaKT1|v_ctBhw`!r5t9yO$>OyDS!VBeAo|~9mmgPT{Ty~z7Hz?$q zf%W5~)Vb#`xLA4cjO`Eh?RpTR%{ugT&sl3)rZw+mD{uHmamjy8-sQQnHpX%HS8UKz z-}n8C z9TG_kFlE^A>XVQl{oa*nhfNjz*p#AP$n07ygx91y&w$(Tj6X_p3H9bOrXQT$)KU8l zB3>#hawnXRd%4I`L14N07W%EsXCFH=9ylu%>0@|$eMCBs+Ft6Dm7yt5Eo_K~OI`M8 zl@fiHmb=F|pUq4=c~17BhWwAuXFjk6APy8C(~9 zF2<}SEpiHb!#DjWm)Yfmd}n0&)mTPredsauY9E8zQY<+OcpiVcn6khsuKvgGyhFFc zOXGSRHwV<~SgKyhOR#cfKOiDfk@Z83F3(?i&w9%$tugtJ$85n#}dcdL(Znr2VM3!Tx+kl zb6!CcbT!y*)34P^yzwhGTvJyvbl1JUi}#s-WcCSZ|JXL#om4{xFU^ePM~y9Ca(xM_ zy3C?;cabFB{GBbLG=BPxl^f{TXAP)t38$ zm;NhLXU(qs-Fd1^%AbYBjrMf7+ERCgi|15GU7*`u(siudsr9b&k}qpy`EDG0D)n5j zB_!0HX4kr_n{pzFJZWoQ79ID0M04jo-I-d4v88H>>tD4nNiy1n5o!9DyyOvV@;bX_ zf6Q6loMl@FZ;x%i|0@uanAv25uWKK;=oE3M5yz@*I3UcM(`^tYsS>1c@vXyl3y1d5 zW$s5xj>$LqZXQ^3p}-@CuzUBzE5sgvxve3jP0nE7^Y=5E@=b>|m^WM25ieyCJ-oMf&2 zaIT76voN zM4hmo;WG~W3{t^V3-9%vTJuPw_Odtb-ggc$Z?S-)z- z`h^Tqx8Lo&%3UA3Dx-VF$|H{ltWQ3oyMT=!f@PZ#&06aK>Cers>8PTk>&1 z#%La`RQTE7_WHjUj0x%7_SFlyn)2}OvP&l{FX|3zr|Gt6r*8Gu=zlE{F|t+pj>_c( zaktA2{^uq3*7omo*nBm`NB3ff+o2sPZix$C2yvAt5*6ERrM1_$7N;3G-~BA3Wl7h> zExF;gWP_5ly)oygU+AB$+uEdigVH})npgMYeExh&8B+@?_P*zGb4w51&fB8G0{wD) z!iE)NMUu_WgFc+7i(k4q*H&_@*JEKp5wGspx@>Xd=A!paKLTEIcMJY}ZSC0l(Y1g_ ze8gRi#=E(m&EnZB-0N4|#<|OW75|A-!3$#cHtFjuG_L2ydsZhjr89pm`@Br5xMg{Q z*r9u8upiIkmIyrYS)mbw<)FU3Fqx=D&+pgp9=CT}b3bi{r_sj^N#~fht*}^q|400C z{L5Xb;WfUcHH*A5*S5KR_?D-yU?KN1{i!ou+9p^2Uz))-+?!X)eBb}_RKwSMX&+8y zyu9`Kf&AzLXEo66cv`JhdywTlw3rRvC^@B=PYR{i=vI6isT zR8^Z>=JJIv=p70UziN?Z)%YOxz(7myGQ$(>>pl1`_>cYEc2>v`mupkNQ6>J(c{_3Y zC9`72JtH4YyT%;q3~n1+{k(AdZEK{&?xYv#7Xq4i)i&j1?LFwREju&Bab?%SUACWY zHS1PBjY*}Y-6-*Ll3LGwX z&uR~n<9ry|NO$e*PJJdSu9$%E$1GoWvbM)8<`OIn`Tip}S_n+H%Yb=B6 zkm%zY*@sM?Nj!&hG*&X&Ey+7mP_saKSAiVfw{e4Q8SU9lJ8`Z9%VQ(F%6<0UXqVZ7 zb4%P&aPn#HlV5^j+Les@nD3H_|{nj@)*XM{{{l^>^>xoJG5v*4O#-($kjSy&5h?eNr!1o46n$ zu(@l{nzrIrw9AOD%6ozqmi3nL<1^3L_H}=uVmiZ9|MQF2DSdkx?vMFnQ7miq6jsWw zW8~8ezswdYLU$yoFSr!9{I`q(z3HCsw_B7#7aR)a?eX64=gcNQtaOfvFY4Xa7ffl1 zD+Rxo)GWzaIpEA|u2%W<2ffh`madKU_obEMLi8$cG|MG1Y}a)@=DbZN3#*iVaexVX z>O{omprli7F4?y(@*haKYV{4ndOE4nX?8F#9k)If>~%Qi9O}EZq+|b@ z^)b&AZ^VWcEC}7fSV*neU*7*-Pw?|9x{6=ERB-{_71Dcn3@c+^9Nw)RsXrF?M>s$K zVr!)>#{2A>Z+BaT?(9=EIwbt_%3IyOr)>^}6`!y{yj!`AWtr&L{J6-F_t0H@NTQ_s zpoe>GSBC4lS8~RmLN_Zp3Vk6wmMxaHJ9*&Kdd4UIw!AM+)<>lJ+H;P&U+Z9awCtQV zn^~T7l8d9kTg#2Eg_L`$7yi0S3T71}*|Ka{pK)$hHW{mHy`PUAj;Zd)q1pOC;6 zwl|kW=`(az`PC-2cBCDTY5(|jsNJ@8u@J|trHv1@7`BYO{(g0EbzpGkCUwnir;?>_ zc@)^yrT9>*bBY&^1S}3}`$SjUxo1O#Zjb1WjXSJt7jp2>Xk;=GN6w_au;l!nDP!?T zNUU)9tn{fCh84}L)+*_3kodWw*5**sYqjH2chxF-Vvq3RssbB#1qJF}e!eQqKs+LW z`N)Nwct_dW+RCb{gpIW~xapZX@%K0f+`Y3iC2Vb1$QRQW@1iBItuCY%D9cs4NuRo0 zH@KHQRn3@R-)nfcd6CJ(KvDVP{Hw0Lc{+AX?{_UrOH5T@@)$8L{!r$S_F!Rtilob; zm#&ViBU(;7+u5WY^%8#R#&CaSR=IubQJB9o=4nt>S#PaQS<}|9r#TFmtakd|Tj-Mb zr$SFGw@Z0vo_3<}@n)!!^XfXc<*)5I#dPHfq4$V%l)#686s7ho2K`-vxAjk2=8s`S z9q*oc&h+t<4wviRwS3Hn4`Q^=_e-*`N_$=K*t|Yx&C;9=O|-hroD8q(*V3K2k)9)- zaZ!f2JpM(938(8Kfwg%@&+{spHn*Dv8?Cw?ugE39@K_^o?@pqyNj{A??QQn1&{}PI zS^h&+iS^;vZr&|fBK=e#EAkxYIp6EiV~$MBD)`FqSEAH6Y{%GEgloFSFng+}>f|23 z_=HXO7?;~xy=%m{VkzcrEoY8Xaa|8T%5Rn-U0eIa)B8anV>Z*awRK5~jf=NaOTP)S zU~yoGb$M2nd0H8lSefnQ@~Y1FRza^vh;Rv4_H84Hq^rd{(lYioKm4P#s#MFt1{1}~ zBGS9%;Db%8JGrinc!eh~EC1~H#9?h~d)4uV_4Jv%?_&#A^S{D=$lXLQ9sfenj2Pi_ zR!^rhy^fRKIywI2qZ19yH>E>9tT~l;XFFzvD;Hi)oGB^mqoK*78&~|bI{HHDHig~Q zH|5#pA$VYcSe8rSxd%@@_Hfp}#$HhxSQ`>ASXjGozhHrDTDy`FNBV^i0TJFE*J7a8 zeEO@lGDKE99cp(m3gwd?km1!}x3E`~c-b$v^0kSV;ZfO(872JdM|H0_X4%CU>(w>9 z$@1DadU$bM^Fi*$QWky&-XjdGu|D=52anu|(rPat{8>A^_e+4;{#1FIh)doVYE2hA zX)EI1WeeT-uAP=qOdBVDK7JjIb(J-9$?Kq9dX|gB%Y7_wt~@bd-n`%uA7>8Ic*bSn zFhb{-1pcyGvVT{$*Upu7Ql>u1s(a|`f_N3L-4H{o0<-xfmC|clbu(o^?InIrW73-tqeHQ{U>v zt{8NA_5Q?P1Mh5mT}-%`u&Vbvg<4;DOX2!|m0uFxoJmL!`Vn_SQcJs9uB6YB$3HkD zMX0^?<#*0(%|sKA1lKS4zS5T}FMPxF1!7iYo-49ga^A2<-k(~wCUBFQU#Q7WfhJNjxt{pVNrWU-_D{AeRR=pwK zwDa36f7`sLZ`tY2B>JBWn=^E&sI;y77=@P`B*p-Tam@zNAX* znSH`Zw+s40td&^7-&&t7{jS>F>r^)$#cR+U>;7~#v}EBC=8LrFEtC4Lg+7Rr|HIX! zsJ1rwq`_0M(rg0>vxP)Ae7?B#Dub8@x`mHEY}wA-rZL2pou(`R0D@Bl~A!11q3y*i%s8ZNwGb~$IWmp8Xpk7CCfn#SrlgEmw7WY5Z;pbECp zsNKhx8>FZvV~<4a__L^@!S*Nahuu>-m;EnNSm~`dm^D@kYMjqIz+OSCChc_nz`$1N z+jwK;k9VR^F#ENQJ}$#t%Iyv!9Qz>sun_0_c2jR<&0CWmmOIbdwr(yOuv>QTa!?KL zGqbpBAFpd)dZW9H`n&Mc>?%hw8|&{$_biX;Yecf`Ag&a5X}_E$wK7yXTjp!nu9&5C zKU4kq&$uQG^-;aqx28YMCCWLDQ@pZueO)&jT6MJI4plsiGF{E?v_KmdJ1k_wcKyoh z5`*R)m+5|-W$dv!zPsyspCn%I%c6BpSelhs-!7IvT;{{cUMQqkZZ4ssH(W$y4_~9E zyeRt#CM3;wDK+)t=08MsZkm?0aU+pCQ?9m--MpEaO50_l8?)xnn=pDYrguUkuTFYZ zRdl_G+UGs8aYUozGJmw{x5K6>M*44V>fogAB|EivP$}Fv68JQoF>Z+CSu&@}7n{Rz ze_k+b#x!hS7LezkjX8SpfT^1K_v9&e1_)=9pU5+`Mn7U1dit*9bK=Ypq ziYMgu?vesLfBY0?$XlDxsX2~C>T5P zghxM+b)9d@BN;o1%jJ$~_6Uo)u=aL8*j*XwdNT=(YCw);<)2o{Y#Qc<$VyqV&q=k>bu z8TX?+`s97lXSSG!J;VP#{$tgZUu`Pqmu$W$>B6_9-!y}H#~y=#uLl-gmLIXr84U0X zeN}7z>XD4t%N{p}rTecgww5WsCA(&+&{16flLZXwEG74nn=-d1h95NHTxE>g%(zZV zQ(*9EGPWkB{N{=s6TxZ}hTR+hpA z!AV24jM4YErZpy5f9cHIJsj$JNrh$K@CX;Sv(C=^T6avg&t}5;Pg-kkUXjytb9g6p z^LOA5|E)aYL_JTUOqE*wty`;=JsfKET(~Tc9zLv2d$icBT!6M<_!HG@#rL<_oj-Ai z$;gk$TvD}_lHjWodY;61BjmQyo#quHH8H17KfXeszrADO_uLjG`KZFvAp?7(QyEpa zXs-T-*_(n_@Yh?SbJXBju6#S=CohkqnX-OTtVeE{ghXnLrpfh;R@0=PJF=eT&GL~o zs(n}5zAj+sT)L>TAJNI>Gda1sTdV@lnnj)8>2fSNvbxym=?Q+`l^iM0<^9P-5w-nhU=Y z8|^P%J=&p=D0?U4dCK7C_CITP-IMk|q|>b)**s*$Qm~t9jpldTp5resr`1@ha@+{1 zqg7y0zH>RrRKDR_7Q0l7`1^;w2ULD8r;2FWn>(Lw zi1^Xp=pgLPGv@dq%cygau-4LRL6jolWcG*Jb%BYh(&diEyWaKQsVgdB-Dz9S?5cmmN$K9yS^HrgTZ#)mGz#@{H6)YY-bQ(D5;%?Jr$*i3lJaY7lDOI2TV*^9A{I=tzM?bkdtE>OCwd z_YPYVf4|y&ZTaHcQ7sKL#_w(&I!a$HI+oNjCgUG6l4g3RVf*J&`#|wOKYVh(`)~+U zjaltaV+^BK(vcc`ecMy$q_4X3dp|az!hYd5=dxNFPJf81`lS5q@P>PW)OCjs?PkAu z(d>z5$2*oz*DuAH%g+b+oMS9$Jt0Wjrl-ZqYe9Rw@y&%YXH~n~Ee=bb%MCef|M9jx z8T*Oo8hd&0ZJ18G@pei1q0paq7l(W_{3)Gtl(+AK$ASczJgQUi<}G{Ebnzdb)yXHD zcBdTKT)$eU?=kc|I2+%~Qg(*UU)!YXgoJtZH-$IJmALj9-g)%+NAEqU64~S(GEth3 z78$wU%UV}x^2+P%n@gADN*;RJ>#D>jK7HJEAg`6S)6k9M#?d%Y)24fwrb3MM*$j&V zUh>7QIZ&fnyn`rXbhYZ?B|-L^&l&Y^;0S^aHP^QDU%vBbYjJIf{GH=e9}lFjyRbh| zGlZe(Zt%^GDzWaP!eY-O@x|v~v=+vBHOKzm)p?z5M5e|4`3-g(e%CSIZR(!USGKIf zo3wET9~ydo(f942Rb`zWub%}y7bBj!{5ORPY-|(NPdGC3P=85IR1eJ_dl57oBlaxeMM{bHy{jWJ zgMy>Exx3q)9NM0hELwkNC|EHg*EIe6N5g8>t0Rf2h9z5-o_hx`1$evugLlp4Lxk z>)5Y&4;6llCgLNFdi#z?8JsW5e*5I;As_tXmOuBpwT|EC>rHv|+wHj@=h?adm-_0x zM;|q%zId7JhI?Qz>e5?VNarcer+)IF!TTZ$!(JNq!8Can!b9-Ss}! zMd7d+5EO~acF}8*J#n#(lQ9qOAqdM6O zJBk`K129+2Xat8pb{o^k>8y;|I<(bSzB_-7n0?zr==dM~ZUW8NG5@L1{6K+hwI z1tL1i)hw;&{uI+zNM(%ex3(ABrm1V+$Lq-Pl3`mre{pcm%{Q6+UPtdq6w?Jog&3Zj*m6)u^qm2+6Kg6d?gf`}@+4|FNAWZ4ax_rV1#J3sugcYB^* z*xMxX+qD0dzLCq#4{_Qhb}MMro%~HA9W{7_)%9qVXjOZPR%|@>FoC6iEPBOyBO`^< zgk2R)={!o zEc2kpH>zbWpgkI5Yqf>5*D1UH>}#)qwzry_cW*RaUH`@LBkzNgM6ci;f5~5Vp7ttN z#3}{2=t7gU-rgf?_2tKj`wKEp+<(1OC7zwLkVW`X1;NBeOMTSGmG@!km*MYbr}|9w z2Ob)RSL8Rk9yUF@uME$(z*p$u^XGX=3nKeZELgdA18YwzQEs7=n(+@6tpl>scLX=~ zRj&NumR%q^ED-q8LXc-|2M`<_q^9y(?6x+2=m&Z7q6iovLa1nOZB#6+#45X z$z@0`+?)0Ot8n&5y0N$Z^nRIl`Hz`oT{3qmc_UPIuxLwOQtx*ECBN^snGC;WZT3jI z@<(wvc=$tlO*w$;} z%9z9~Lzfc2;Y&WV$hjJU8gl-{@G{ZSw_>mjB5%;atutSoi(b1~$x@ zl+ubv1_4I9_{+4!Ur8R*%3gTK-SLHCia<&5dnczD$zN?Q%Rg-2s*m#xtp3X6u6(Vg zSTi(d`QG7lcT8hkn`KhCWPat3!ibKq%a>7iKK4?)eUjE`aewwHI<}UEHG5buEL z!|~$yBBc`D(+9;J3b?LsQd-;^b-is>RsMmLpM^~(x8I7Jh<6`l=ziC0;-vIaWH$?T zpZ)59+M;wW;nuV#h06zt(WTSsyD7iH z>St-}a^DOvw|{$f>lHM83)v|V~W$3iWzb+SsfC|d3vv!pQy@2Py6ZO zrR*5ftByM9+winEsLO&Js!d;?c4cAM%c{Pd?bPjLYTaF5TrV*`HkMDhpM1xGHRok@ z@w+3E!A6x=ejM{w_NLxRB`R_)yh}R!Ona|Na zbBVsQh|O%+O(^D`*;ilewX*+5*gpjc!!%8R=-9Sx+qP}nwr$(?%rmxa+qP})`~4B; z;zVr3-d6QxS9NxGR;F=A0N+74c6F}AeNZU25us6V2I8nu321Kf*4?*cS+HZ;k0Ydf zj{adJfHve`aoRHPnvi7Ll;SaFFWSEThmP+!j(HpS(8Gq2qt}bo-%V`T%KMUejo$Xp zZ}~2#?ON}dT4a+~`M0Y=PYpcR%GPFEby=|e(@T@o>t0inRBbBQfZy!40sN;vlc_tb z{E-^ackM^s3~fBt!|nB*Zi2+^<2iBST<$YJdbB;ayXMv52ljPuv=h#17LdASbt_LN zUCYA*7M)Rm@aES=ayEV4#gTs|cb15IiAZ!ww|3MVQ0e(>+rNW)vj zPdWfc+Au!vdj~d8=erL>)3*51UfiBN!Z|x&4Uq+KZvPD75ol;FsAB3*o&jM z^3qTcpH7H8q}7R+Qs|^@LkFfD$(l)dgf)XZpb!ibbEd7@K^8x2)2p{7xHL42D>(AiUN8PS`^ZWeIrruv@>FPt|voDDAAWCcDl0(w(sp zyRD89n0Ln^SyFyH*sjGYC9tX})-#7B!MTZ(t?B|RwHqm{wk9!yi3_$!9)E{021Ceo zB!DL!sa>j^vPEW)Fs`Xx(8BqcP)N6gjse~WV?(SA2=Fe&>!4asW;s6^pD->jMD4~o zy@X{3GW(EQ79hu&UH*7hG5M?WRKh)ygY=wq%!&~y$Hz{Z`Y4wlja%0&K0q3cDGvNw zdTD1E#O8dh9`^A;9P9kh1U=WcgNsjc=9*of-H&O2r>vZmo%HkWixX zE`k^Se)4Em$#d;GhkBm75huNR`k^^q5}C!4QARx}Bh}ALlv}N{yZ$ilO~46Lt+Z>*SRw&_W%#I0TwL+2LthBDHlqBQ=&` z9Zpwp+ThXO=JoYl58>~{f^M#%cuLO=uzKh(HusGORdC7ybqzwinlLK}H-I1qf}!eA zfh}99wy)Achigyt{Nr`))Y7dRPjfv0;b^QwmkVx<-@t+kxpL2pkb0}>d00lxbX3g{vfzvP|Iac()+{{6Ia2H@xi;3 zDJejw3liXqZADz++scrf#bX^zzr;|UGp(3=KO3jo&Idp#9DXndCZeMdrN+q~xOV;4 zfaD!N^mu@6^y`%UI00AE`|hCv6+M zuqB#(h!P`mYK${5|9%@OdoG{RR}SXaT^8%UbT&3)H1GSHw1E>7>$a3_RJ_pHg@TL6 zrb0<>7yt0>SU(1rx1kkgFJGPVkSJ)L&(l&|63x;;^@!*-2Rc2x$&Uw%^;ES~CI!_2 z3B+U=Z#lX>F;LVqG*-^`V9}-{pO`JpVDb~$`^g`jb!RNJd|F9^f|$vGK&i_zovbEw zID=p`Ilc)TQL-5)yB(T2tw2pT51SuA(x&aA876xSmRv0G?)}9UI%0qpVd143r#EY% zUFn^R(g;EA0>m0r1}+F_m?5qKth87);I@r5C+HAJ(2}azNuYG8~c6Q$RAg$7b2lJ8HH0+KXS}4 zf%6RC}UOs>(sxsGhT?67rI$EJa7ejj9&S}T(M3M`%u-K1a!+==_3)Ha51fV=$0h_(WK zS4@9whtI=1;LK%c<_ytEu#d(RauV2c6JT#B4nWZBsn5Lpdalm5D3X}4EY}=={8y@- zsbWZC`2pb;tztHAMlf+k{a`4#h{S^tNE}8u86X?G{#F;IRTVXse=Z!kuiCe5JJP7X zMz`pEZ@nBmuJYAG#|OTNafQ4*(oMz|@K;U%#?uI1pP{%z1L7Hs!#Ce%bdIwIRKoFu z3}qQOvv|m{gbbsXBfRSz!`>LsTNb={<>cKU4aHc(urE>9A=tueQOqGx)Mc&0@r42F z$S`UmH;D}sS?o(%RE0LKj7GBtLof&8x>ip8UFyy@Qx(rMK^mB^4!Z_wV7m;i^|GB; z^`Rapi#YNG2>l}L;g}%5-oiOR8R(E5th3~JMDxnsm(3&=+MaJa`wKG_T zMSvXy+y`&;%}jCGv@K}Ln~CGX|I(Z`!#QYEOUIJkrPKWXndgt!d_7fNqW!+s8t|gf zJR`&rvW66+*7EU&6|0^ziU>nAdTmC$VTb~MQ;X@^Ax%n2Rf{0P2DlE00Pt8axEJEo zkhl&=GL=F3hqwZc=C!r7R-Nn*F{x`fG^KOA;|}(gfo4r2*ViW9b3oYO6iLJ2x=HX+u+CP6C$QTo~|=KF~smi?-thj`Ey9( z@7)i?-*rFTm3RrycjD~xscx2&OLuxALHhyoGqsEJ*Z9=A{O88%B|UL6?LUp0N1(_7 zQNRo&i-L+CzT4wRlF4FK6oa*i0)aI%p9jIbK8*1U<&<)(?Exd*+K~AAIs0yuDm^$nv@glWBJ^kH@{Cy%^=@WZZzIv-k`6-laza z0yiw%?@8#~Q|vifCCwC!0OThfdm<;UG!ENS>KNsAL!GvNFLnPi<|`RvaCsy4TTC+b z$Z%)x)KTGVz(521I78pPzp7q#Y;7jL;GQv_OrKwu=j+=y<4z$DT?TX9BPzJt$D>n? z;Hnf<21r+4>n zg}C&sLQo_tg0&QBY{*I0UOrs}pZ1FA{!T)gPeM^7B^)j@$^gpa5G!0f zUO5Fb7v?z#Q|2?vJ4gvT_6x(=^9V8y(Kt9$!cia><;hp`K0dPdX6|QnUinG;s;%^z z1;H0j@M9B*usBZmt@R%5*G>x25{LIkjrPHsM14GwfHq(4eOTo9IX%o?F z?Lu5FTa$&9pdj{c$eQ5*^!m>N=F6{Jqlk*f+Wi4_aUqnc|5p@5dDmp+GPW4X(vc); zq(z>d4J{FWbHOB&QGK}rGnj|+4pRh>x+aykyB9d$8E%b|%c*c(1*~bX-7x6`frf?; zW@rRuY4}W~V6iJr@=m0{9DVB;!pLMJpwdXA3)Y^qo#>uQ+mqG_U+iiP^Fx|yvcwZ9 zOC6~M6^bgl5g>FRE}&@J!>7y5fZZ`_F_a4EZ+~-7OEbcD5AOhh%QiFqO@s$U|fxqiMJ5OXOi1J!K%U&zmJ<(M0Tcb&AQ@?X+iO*ejrl ztLVNkLH-+$nHtitqD+dm4UPE>Z7!x>4;pn}!+o)M`0$PG#y!#G)IELowO zzt`H-e9qbL>d@Oc4YbM{2?Ih-ZxQJoygBR~$tywMt(X~}NMQTjGEy}RWXsUtHhvsC zpeHVWR;c;^btw>xy91Sq?tAlWGpXz^KeUNETG8H%? z0LJJTl6S#S^nlbBdH~(ws!C|m5dveB%90IIT7YPr)MG+=}f*+uH+W1Tny*A-0w-Xbb&6d3mX7o|Egr{G8JD5 z3?*>B&>%?PpM7KXj%Y~dIFbxE1Xkf}(w#2o{*VO?o=MoV(DTT6HrY;4S~`Lq7b{AB z)=#24w@wb$Qx~bPr6XhRLJXFtU2_M)5$TxPZR*0N(|uuM2V%&LbHC;d?T)d1AdLbv zB-_KF+VzsJZRx&$mZm@Vbo08I4#JMIdA#D71r=ugTv_Gmli<6? z$BBs_?0*{Pfm{eXzQhywLmMj5&Vc~5Kgj7&F&JcHRE3{Z2X*b$|{d$c9xzJ)Q!2C}Nku3N#{NB~eK7%Zyi zd*OJ$dP3*+gO>orNe5V6FtX$bs6$V8)QbTb6 z0}xmd24jPaAi#q$hF52*E41G?xSh3$AfMvlQ^L0`++q8;<}jIrF(fXd^LTo--;Ce- z0e}D%@XR6qFX|yI{}Vs?|9RK_e@+Rpa&WNz|4j*1t6ymya-sMJ@qwhb5};D-Pxr^{ zJETulP(T#J4I+*ai+A+>NiNQl5n3u=<)4SQzxv*^ELCp1vb`NuB}k^AXFFY*s;M3n z50s}<^w>0!7fO9owN2P`MjlGK)>e%87;{LVoP9Xo3m*09TpTuJ_$}7X&F>B9f2CiX zdX$?#FV!Y4NMAg$)FT}QYATd!)XWG_QbE2}RK91z{6nC*1u|>prt{NOaD)}4qzW4s zt3xUsU`drD?NpC6GH#wu17qKL=Hu3UtQ*OS$`{j?R*8%E!T@MD!L*h0I(csDWvWl@ z=QvgTXt|9mk~mn#V~Zu&4bVWCC8=Tu7B_tZyA{9|Rg}aj?xLVGmS>MVWWh!cPW3<2 z=3yXADdI91G5sD}{KenN3BiWsKxeRGY>nranl zUi+bPAY7a?Ti?zed}_S&e12PvtSbABMS*$VufQgh1xa)5_fR-jtj5Qyj;Xkf)FZ(d zWuNts^-4ZBvq@=sw%L+Dz~jo@J;Vcc-C)Z|x`AGuQ3$P@%^fV)LyJ^q2xJxJSg61Z zK=pjII%&eH$a-16m_yG43(uq3CVp@5zQlM_m`J)UYJ)(%WT1rVPrRfv~u zXHnA+nFPqZ7pf4I<++}^rMHF7he6YZ5M)}sw}p$BVh^h<>6f~mB|=K*DbRYn>XefL zhCF>XuKC|kj56;)H8{K&FrBAMNRd=ExDW!WeCM5xcRN__j92c4nDD+zWk{U%hvK-0 zCul=IzIov=|Ag9j#Vgf)hpZX*M};m=tRws%n_l>V7?)hmYj1Zods!#h8FSLgKwryl zQsqn=nL&m_S%N!L)}^2K+EV4xfnCop;%Y$88GdUIgp2`By;j*!UD+HQ zE%Ql5%kmeSX1>`Ze8!_t4;t=$p3(7(yWr16`7S8+=@7lH=PRWiZA~htGT(6G5_tr3$YB{+p9f4 zSI@`!$ysmDOPO^M!^{|B;N%cAA4P<4$j{LwW7T4vKvYDho{XMkyQ^fOqV`b>&SYM+ z00UtjsYt8*BkfTIAy+M~Vbq0mVbZLyqLMIrwZyE;YzCml@6@t7A4WdO2o-`E3Zk8` z^I=Js2v69^G*i>_r5j^N?))JYgsnb;;#tr8n592s!8XGXQ-FBiKj>O^y}g$m)K!Kk ztvJ8uey*-Z@<`J(o$Py}^-B=LWXuo5&xrxaWu!rWOP~JULYm*z9dU&EcK5&0k4I3; z0kgVK+3Gbw=Z$M)6m-qUvKXwM5-O1(x#Iq7b=J3vV(9=nD<^z2*_euOjohVw@>w^n z^sI86EKQF%LYl_7SkBbtffU^^`1p0OysGevqEZ~Nv2<91RpO^cQyFNfnFeAX%HmY= z@Ycth=Ar6aCH;277=@j_QhP{dbVgdq&QE5{vII7ZF>4OMoZ`8jwB^gVS=^92GtSA>qoJMlWRH7*?3#(GV)O5b2Ap4}Fyv$cFEQTw%I#1k|{pfxi@Wk@M z!5$|awy+l{=MfD~ks5$2+iz zW82EMV>T`b(MW+=me0HlADLBylGn?En8Xv3g^J6L!0%QTLHbz#UsEMx(H{73(g{(E z?i33viyxMccMNfUqM7<)!({s{hN`x(;$0WgN>1KBtvHz!XtJ&mWdPSD?q&MF-F_)$ zabmEk)j#<&>2I{&ydI5XB9nvBKG!f6n##caJPpOISpbbQ0ryAlO0k}9t5uJWwVn*5 zc0@F>E0)Bo!HiO?BI-(Se7PqvAOH{7hPc>{t9a?Z5}Mll8vXRFBiRlMwQ&0mAA4zn zptG$W{^&eyBWu(*?oLthVZ+?_f{Kvy6KoYqVzFxMAnp4yED7!V@F5M;L-rAjE%*<( zu~g$F=$c18$z5*)QML}XvY3`o{4(Y@G~bgYc)JK&PncTp42~_;HcDG^n1OZ3tA6ja z3nON+CaCql$1Zqpn4pK(+&aAA4YuGn4Nx;iGVZ~s%P41*6et9#!Dw1iM;Lb$QM5CS zL2MxdxxuY4V9|RFAZajw;!-o7+iTu4H0<5_HY{$=#dNHIqLqio}27gYqe)G`KE{!s}@;d1-9vjdt3>qMN)b`zW zM(QemQosQjeaH}Ax5_J`dYS!9(2ZU=YAb<4uIr~`kl-STLzwM7X7<^a%nnQBbRWcbt43v_E?=e_IzO-%NPw(`OSDW4Z@gb{6 z!+|3iO%za61CVWC-Y7gEZoW>6Illi3y=qT`it~h3H={#&M;j8XyF3}z=PVFw0gQt8 zEjp6{Gx2{vOXe@@kb%c=2x9#oM9@oiut&}rv*V|5Zs&EIg2)A60vE`k1LF@vZFR^ z90F6&hSAbBp@L>)#3(rtkToD(Iy3RbaM9@yWYRzFE~pEzJXE{wHk0vVP`@n%krwM` z@7`UmRN!_V<;1e^ly`^kH$^vn-F%kW;DZeI$@K_psC{*J z6TRAfP6Hq+ZqUV4BioUk2V;}-NlT8R$(p}Q$WXk+3 z%xP`pD!<&9e(yW`UD_;r><$Za<^!AMDw&u_Vt zA4c)hHUML@abxsi8pJK~D9LyKO|oummg#eR@T!+;t0K-F z;b4PpLVVyAZcC$%FQK^0S<>AlOrcyss(5OwDYBt89~;&22!K%5o=LA@%IhsGPs$j9 z)nN+F`eyIEEELXa^-?VUd~L_6u(o2NU~f}f;Md119^C06AlzUpK9p44x^;tM*XI8N zaToWUzk167!SU+W2g?rf0^BOfvA#1^siinI;90bCMMqH{Yo}flc+VxOp5N%XwH3vd z9jvoqs40J*gVL-zdS}ad2y!(&dCO4}S1Vu1LqZ6M{!XL9v}7?q&Xql=_Yz!i!p|rY zFYO5LzJ5o!w&k7ZRL+HTxJljjD%pJNZ9H_Pa2eJlgv4>wE;=NUKhT=8b1kdw&K+sl zgt(9=kf}l#%Jd|OXG(oCv%B~f%WK3aaq(%S9U2QZNgpuNO=^@aUvI`JgI8+FU8p!P+EK|Aa6-^3+$V&9)rE6n|UUDX$o=7_#arLL*izl zSEZi`N+C+X$`bjV7L8H8mF+_HWdos|>1#rtsI`N$!1%$zI5n7Pc&}GJ=K*}Gq45HI zg~wOgNL}?WmQ#Bq+DeT*3aKtgLBC*Tb*td8r!z&z2gPl2=-C-wK|f)IKFg{3EO!&T;z_;Im$IiKD`SJh(3eMvs^d+a=FkF6+^``BH5( zakX}O@{DKy9v!*D1~s%3P0ajOAO1nXtnsj!C#xR%046Irb=SG^XyK{Tx5t3jeO@$2 zM83ukVQ?bjv{e9$qqyfcqIl7y{2?b!JyzYHvNck}eZ2^c26F}eHH4uS=qPRAQxEK$ zW@Y~{vZ1WBMhrXL%kpNE1KGc1Per=pit?xCKv*Y)px?ydLwqe<@yE%OaM_Ie3E+#2ap?iwN+)H$k}R;waMmazG}H)JmsF5d-->o6C?PMkM+ ziPxclrnJ-`9ckzH)TL7%jlgTi_yKCYyV0Jx4C;ejd=J_@wInhjNPD0A%@tBOGEAH# zI`i)x(Q;IO$Lzv+eXO>NsN;T-EAhw4D)jNo9qaYQ7fX*o3~K<$D{?JI&`dv~7_C+5 zJfP(T21(}g?|E_L^D!8#8_(G{L|Ylqt`_k4*(Tt+_a&+J@7m^s`#hHuwwCGo70D@^ zfQbNFsY=xOhP(QQq79DYAbe#CFK4zxTqWtH~v{03B)!K!|NV4JX zt&yMCgd5?6l(XelP>`FHjRN&3gep0QuQ?8!l*h;aI5ho&EP0SxS4%GR_KL>ZS7jb# zPCmk2i1puLGCb|C2fbKXanqh*C|M7P0%Rnu;NF!R>voXMB(ahumBM)1&{EH^0e;x;}q16I(zfQ2nK4 z;ngQ9G3giot9LaEoZ(kx?@1+%*DXRv% zcDFtIJ-VWb@oywHd+OMk+8J9@NOx6j$UIk$pdp6NZjsxn;~M|t){&%+_ZVPgOp;W# zFD^;(q?b)V6pOMH`?OZ*;ZwoTgu3;uBPE-Pq8+2>Pg2*_Ang0{Ps?9gX+pO#e`Jwl zy*Pq;42aaPz7qfH!Kk9ocy4?p9gK~j3!GVQ!@tT>Z7-6F4j;#T+TnX#M}_JyJU9%sVyGZF1Q9RYM&=&fX=OQF0N}zQHsT|l}GdJt}d%8X|2iqbK!r=>p zvh=^JozFc~PsjxGUmB zlxdFa{T4R(iH(uVU958<+001>Brtd4EbSy>jg0PMB%S-Tvr+u*_%W|o`HD%chn=bCVf_Pk9thx7D)gpIo%W!Mpar>T%`tE zYIXVJZ$0KHS2_}R@O7j(*%;=&8NW4n&&Wp9!u6fBRo_L>snCd$!IqSCD%|;wbs+qw zL?@bjs>A)%9jFIIS&#|8A`_@!>ORaH(mGJg>HME zVlhEv`l-mWeW5yLjU!-&1v}KqwWy@Cf5K>>Z8J;DlP{5aYKuweEA%C&L14y(;n0Ww z;_26O&)&X5Qksop)5U=LZ)a$uC!3scpLj2j(&1BjphH(D8M_sR`1fIA>z6T2*N)3! zEyklwY^uBG^p~ZK8HbyGs~+ zDoFqz8nQ~Z>4XlY@3;tC@CHk62g|gBy@tRs47$}Bt|apu$f0@C+~p+JEU;f?0D0(R zn>1?CVYcFX*tWG&hwx4-Z6)&Jd3xtH7Wh3bPy@|o?QB18ZdiaTbhwvL+OOR?_o>t! z7f8c^pU&9D$S8xTNk zy3a;hlPB_t`U0{6-PhFu4S@h{5Ly2SP~?LJ7T!W`jY`pmHIBV_HLZL@8oKs_h`4Di z3^v48dDk@g=zYcsX6aj3cK-ouHW^qlg<|wO5*e#>=FdvX z_WDLcNYj)UeC?=lz*(yZ_zIIMl>1nPYpo}J3PCZ zm44We(GHF)_r?>xuB4B^LmiS7cYiMd69u)8Dg!?Fm4&TeVxIH){XsoA5yawiMRc{# z5YO3+62kE^2mQINzi&}q6Qp1d)X6rqqmP$VqQ_V8V<~_8BYs;W1BKaYk0Ypnsr**! zu5{K$65}bfpj-U3m=^Cm!1Ufxy(^C_R?Zd9J4(h3m(Y0{Gy@p_DztAR^nJ$$jbWmO zbg-#WrEioKh6>HKQf2q>j8-p8YiWAfdNxIl`AI*mDfMH+fi1yUKLWmIF>d!R4EpQI$~Zw%EC{3&4aIp>ro~>_1Dl?^slR-m z2u#bF_En?ufjJ9fM^56?fVBkf!>^)Yq{h%^r1Sf2J=-shZteN+@|WdCs`~~iUB}4! zcg**V&QKlK+--1()@kvd6e>Q)tujY8U&&ty){?z%DfW06gZ6~cSAmNZRN8Sdn3)vFZrX5MqK9lh1J{1$W0|jK#|s= z{46OGUAjZd?k4gRqSMiJkQ-jcutlvLPXD2yXsRJB1SJSck|Cz zbK=t+y8KZmtu`iuIEBqA%(pDF^AE>#$#6`^9Q@67v12LXwT#p7zh+Vx!v0MRlV5 z=u+4bv`HoQlhGyhtt!cB>!T5279WGo--jN_UQcgWfM-zCLxPF`Ij-@;oN0nSsQ|wN z31Uu_@=D)i*6{0Nz6Bnn+!2%>LTvk`a)ec!oF+#^|CMZe??1m>yBVsnxPSaq!cv>T zm*iDdFqsdkKHgzj@{pkAG;2Mwws3gUqWU#Bt8W-F`dqIx-WRW(}dka(;ZkIVnRBzQHBEHlc{x%`1va zHlfI(X)m)1-^Oi+9?a%1VRFr)Fr6NPk#=ARw_7xs8db5$r*&$rlV#HyN?c12zj?cX_&TDS zKD+0wW)!bH9p<4L*vo_R?l`}TCU-&yr{Bdvcy`(xN%ou)Mz^ocEt2o{aK1tDJsiol zE15UxWMnZ&kMSp0NI}aSsI=y~UKIv}lPjFaJJ;pQYrN{{c^0+K_q~DnMh~f_H8*Xb$aU_ z$JtMqc}(fxU8ygymFGT|h49`O8NhQ|C?pkN0PANMhA{Ot6MpLOXHH`5L2-yj|K?vT zKj&9pXuSIEYBGa<_ibi}R2#Q5I*HBP1~q$eNK9qyzQAFxcSb;+F2t-jY5FvL20y4XRf-`KGqhN+Pm3ILN z8r)V!zA5)*#~2{yCAxZ#Bb#Rac{MhI40l1j>9deL0*k~OByp?gY#@_jqX+^w+WEPw z|H3^4w4tm&YIxZC$`=`dBPQsu{Y`;hkY3vXBTm{Q4{Jtq6%fN=V|>Bx2wuAwx|7AZkKK@7l zP4TxLoSNFBfH^WPHSQO>UbbP#NZ)&Ra32rvZR)d;ZSUsEiIp*WIL+99b-ZtM3Rg;d z%ts2Fn#ylNGR2qqFC8?TxM`rHCRMhZ#{u?f{}s_d_fxW{>UU-PXSYV=jWp&~w0VZ% z9rTJTn#McbplmtWiSwn{;f2Vp`UMwuaIy}U(uKo~7BVD9iE&5|8jh+`~LBfJ!Zcf_rrZ~ z(&G)%^hX4Q?vP!C0Ii+y-Ey8Jgp0bMgN~jTC8){fF-cVUF(~M1OT3VcmT$(DpM)jM zoOk`WnJAK6>VilnX`IHs$LN@!*x;-IuADV)4XaM@!f27QNCbo+cf%crMCH=JRm>|* zY{r9hzPM{_RL)`937J+{s&@{ZH#*iV#=}&FWeP3X@RyYeCFf0ju^TbuOm`{CxZ2eu{gyV4a}=lra2JC(z#`E5t(){_ zY-`^MaKMpnrf(GNKQ@X}Knjc=@?%UEcBbJ?uqsrJ*s_mItSHxo2;o{`Qt_a2 z^J8MyWREMNfFmjYewew*MINpSirc1lD@9RgolrMjLN=0d+Ei3tq+D*WT|bbRJsJXV zR}rwFdXT;>)VCclQ z=G2@Ed-L!$*%CN_c0NUyuJ{M(Dt_`YQ*O%XkvCX&y?e1EbzMy74s^gHHLPbx+|*LP zF<7Hkmk7Rvp+SK0veLv}McG%SNw2H!&~(EkX(UMtWa}2bL~4+>(gAQYOD0cUZaKz- zCUvPPvqDlyI7o5CTymi$B*6A~an5H6cv;DWSYh#&YJCQfQ6uKD49-h0wfof9e-~Dt z&d}K*2I@fg1$Gq{WBXiSGCdKkz!a8ZaL{S_1}{;uS&7gYpW{MNUdqXy4!QwwwX8uN zI%$PlM*>vlD?)K;1>0nVd_|FbDc&#Ub1;?l;~VMHbuXBLYw~>-$$>g592*p+8P#yd z`+tanGIla*P7ijr1ymPLm~5EhqR5Js#{{)Xl@e;0j%J!2Uq(bwT`I7p6>3)ZdNh!` zkBpw1Qlg3MZR6RES^r9%7DE+hi`5VBrHG&#w&6?ar4SPv-?#l4QD0p%R4TRj=%Jm! ziSC!kYNeu`5(r=QF^d8vDTEszFrdbPeuj-GXkUqf1YXw&3r{YiyqkFiKAUR2Jl*-} z1tQ(`q#9;I`b!)kE&qa|-0cGf3%IQh<5qKJuemrZzK1Q##>BMNTf0i=f2#cxs01{7BnV^mE>5DAEaST39B7=o40S`%uvUmpvE z5HTi9XScp@V+gB~r7LfR?-JFUBVOx{y{dp4DT>{JQRvzC&`Ut6Pe{Ty#;ZQ}8v{yp zX8_nQ22ImLWl8DM3*&WEK^CU)z)G=ZU&oTsXD@ibL;_vYcYSVcX2w_1+_JP|+Al2& zE0DX@rQ-CuU@7=h%lW{eJ5jmz$wkQDNf;_nGCrmp)6p81G3Nl{lHh{!`Vc2j1Dh}g zXUVAgu+c>qSddtJ)t3jhVS;Ot<*Gbu_C|#;KpvDO6DSH}Lg%1P`DY~H(S>t{&VWhn zWwa-m$^47|>SWQUKgabb#tD0i83yntckDxJpXSif*?DHG?I$F|PiW^y;h?79liJ3I z!l_CJMtTbe0)JX3jQkP~klBkL> zWlARq47)p|x!Oydo44{Fd*fRT-X)X|-+=cDG~|+6Pqpr}(VJ&zV5L3Qv$}xnDUblk zJYEea7f4Y{T3e%_IbF-(lSax-i^ZANb0{0Dv|;te(h69{XPD;3`!SLBPp$z%fFAuD z!}f^89LSqJK=R|UQ$nE2sR*ljbtXbI!I~@UQly#Tqz@n=uItej<}50QE*ew`)PMGx zAX}qaXx0aUh~HS{hK@fF1K!146plO1{C&&=xtjf)^|C<$Ap@HAmIqKWe;4t{Vr+MS zpDpDY^*vEn^_lo9v(_dRW$e1gJFKR6aGehqnJ;E35ojgOqlitH*|cUaoZ(a8WExyM zr}NU)rejoK#4{6vNBqa>XIhss=wa~z!4X0P%P3r7Sz?F?iczo#*LJA)-+L`)NeUn$ z16N-UKO5*aA(_+Fu617>;NM-{qVGm4_I#*t44+o6*`#MwyQ5e&CfUxZ6COBfc;+|8 zykS?M(aaETIkJW>578g5uxclU{ZYQ@$UfMOc;ol;P{&Lg%Q}6>#7mvdCHk)5@*nB% zgqEp84;neon13_%kbm251G-U!VX@to&gUce#b5#zQQ<8qPKK$p&bM@w=+@WSIb9s8 z03557PFLt~x=I zIkvQz*dNxj@(`hO3>`q-A3jIqbAyev-C3m>PCbaONrr0P_C&Iot&G%(A)HZ9U^-i2 za*`3II2EUv%UhLyKe|1I8Z+ZSOA2@6|&=TDr#}GHft^r?Ueen4V5e)`S_!?haBRo1} zoj&hk;?GRr%4|JpI=f6^b_rx^LH#+T2Lss_oSg*@q#>Mne z?V^=TC82`FbokZ3TcU|heU<0rE0pR*`SEr5m(H&gln50;-wju%N;q$ z7bqLX-Y9*%kEPv#xG--+^w_#wl1A_VWK~tuA0g@D0aQrV7yx=-*Q0;|@aKf%!$Z6G zXZS7G33gD`lfvv7M7P~j#)%;IL=iDCq9s4(-!V8}56WgEa$lsx$aCB?w0Z3BzCFu_ z@VL_2g7Zv$-#cGLBZe)*9-KF5kjEp(QV{v?D=_>BHrnthd$L@BBa{JN;iW7*!ug;B zRO7zkI2-Hgow6y>qjYoaq0dw+xl(=%{m$foZ<#YeI@Kx;?=87*vlDTTt zE}0YAvzqtSJ8)OE#iGXHteGcI8^2%zmN-OVRPXlsd}z)=j{NXswbHyH02mQ zVI<^CQt7L8ujGct`vAZ_wGE29%rUL=Lg-HcFD&T>4OM)lHPZ4#Q~D4?NEk)!Q21a{ zo~23=o%tNn9!QS{y4!0OtVv@7DJcS{L+ek6#BYPnJGo(Bw`&Hvow91b@4s)@!J>}? z!S7@Zh^LtnU(A55VDTQ}9%`dTmE_%+fNo`ktTqcSSE&$h0AW&bZ!Gt|Pl zb4$J@6l*Kf_BGymz;5MxwRH2g!B#KYI%2MwX_uVbVXQsg8nsW~KIkL47DvGMus}Mb zec~=L^@Fub)dw8Dv3T!Lyh{sXpSpKI6#&YxEd@t(A~|U`6o3O%f8N_RdRhbqa|5UG z|4{Z$!J#!>v}kPGwr$(CZQIU{Z9CaXc5K_WZQDBe{@-xXk0eiAE<&$V2b`{+kU$^Eg7OsJE~s>Zb%b7|SckeufCfuaNsg6;Bes{(<&#-3 zXL!eR{oSm9xT_~?-WH{uV{qk!$L(l9IqNP;D+%(mlHDz#qsdAfqM>8+&RM=)=xUVe zBk{KcyrqY~O}o-<_TwYzHyZ}_(Y0xsNZv<#XjiqK;GIy`^UI#5kU1H9Rk;pJ@_lUs z;YJ8ky|MN+x~0`b9AU5TWZtY&&!?-zyA0M zFgY`6L|dJR1kcu*J9JT-GJJI8lmcIm$o6c0X#MDl>OC$1w;c?OZ~{p@`N zj=r}b7+kqnAM&1-`(q z+I0SnNZFha*LvvqsdjPM5{_id3CNA0(#R1^;Z40rQR9&xdpK(eNj=*~V@= z#eBBv&1DfM;bT0T5jFZeRwZG${oMpjP66KwzoZ`9@7Y}C`84l3h)7T;uDGCgL36W% zkf=k=QROJV{nXLI*-epL*77|gm3iTOQgNZTBg$fRal_&_iob{gnix9KKGJP zp=y`<0rGbGc74BVUkuz-OSggc`ICth=u)rJyQdV~{aE_u;E`{4wl~~zTiT7igA8QE z4BV9xutXr1txCfx-?HKLsfx^;Na1apy%|SV3LbIMQ)#-VYvAwx1w=aa*$)is1antV z03p_DdlMSiQ^ZtJ4iAjEcv*2!TzSE2;&a>lcUSU@CPj}2XpL!1wr*1TQNHMiPp*D; z%wR6;q8e;E0PD0$Z46=dzJgLuL7tBdF;3^P_*&;Tbp2ITitw34bQ%4lL1PnF;y3am z1GX%tx9)29wixB#Kd0ZPOZ?`#M*VtoW2n&DNidN>6|Mc2V05QwEJ(W(A=p$p4(VC zp1OhZds8yC-!x`)!eF#t(LJ+UWR)FlHKL)bR(vI@9N8x zmQNPz9mtfJ4X~tRko7o!ez&SIEcMA3LpIeLA9U4(uJex`3bHIi!OGR0$P7=T@T|m> zeMW{bt9N|u-+s-Z-dYj{4v>N;%4ODe16)M-7-J=#kOLGoE>Wzh6N?qdJbOSP98ejf zhWKf-XadDjek#UK@>$H1uh)nW%i4PSD)l-nw7_UzibhGcSVaxAT(O7x!H60_mR1b* zkTQHFsIybWK%7UzxjtFoRo=xq}o2)$#tsM6D3kADCp5z z0edAe82q-rHTcXUSKlvWK9yZIWW<2nCL}~M+9QGeJWI)QAN5j-SVh%Hdvkh9d%}|; za<$LhQ^>FVT80CqVq6B2geg*>5MMOBEPFCMLpUZo%A+0Q+td*-GXfOh2X~Cv-;X;w zj7)Whr!k_-&cE)t%z}bhy8gPr10llU+8-YUo(S>&-dBMqTx9cO2W-fe#7Ub~jKFkg z?$l&JjlHV7itFAe&)g%|!k(z&>?&b>mA#7yZWIx2w+xfJ^5dAt_L#BLWyijqB z{Irl-GX#rU2%WiMaI+w)+9YB1H9e`-y&DJ=8wIyL+>j#yO~fb64OL-zFv4b1y!MFwG^t-Mpl0_7K`(G=%=>8^Jvd>TM+rJruKj`lY}#slM8) z0`h3y{-fu3e03+(O_9?19qTM*?pXr+fdJ$rw_oJPlaJ_I<7?1ws0)yfq|WIUovLgj zsOD|~;i_89>4=akyU|FRqE`jE%A`<51$cqFib;`z8KSG&Bp|9eKP83XTOZ>FbVQ`1TmtN|$q_gKCIi(tf}>rxq=NiBKP643oZTIw02=pliho6r zz+cu&r66zkPxPwLYYbPo_fG(VpCY)j^gJgC9Ns!lnS+QsUiAHOprn>n@K^&xx+Vv; z<5&u*WJufA8b1I|pL8-TpGOMW>%hr(YdD{B4+aQ_vO=+AC9q8VJAoGD>J2__S zcCrj$)H50xsCpj*=h`H!C@Ihbf`M!jBG|=3ecxCN zN2?yx{v!5UZO_~;y^9>+NQ8`X8rwPI0+;$S%BZ-y>`tSLcaq0s6TgrA`&2Qd(Y9o< zUcP?qMZrcK_mWH3HbecM*U=u8rKCYHJIl;%w4yje3-@`X1A>Urg?+7!Hwklbu?#kP z*}z9Q<_Mx!(yGu882$!38?F08zs560wo5bMN_bOgceE!PpjSYu_3I%0AI%{TFXGDE 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�^5< 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
?xnGaOO8QL=GRH+JVj%hI}TZh2_8 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

D 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˲$FzI`v!6<|%HY>Z)eQPeT<^ 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

FTE8RgzOt)Ho4@J_ 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
    k}u1PQZj1w@HNbPX%W1w^s2#NvP` zB^pZuL?}pfqI-q1a|jSOMLnHR}@j=G4gmINj>JG(E~YZaLx}1 zbRri6EWH7e+vzY(tPO6EWD;``3No(12Q0=|@|ZxN79BxBA{X7u4Pryd5g^ct;);^Uw_eMssq2ve<=tXhG zN(i_`FUmzmv9aVRDCD zTnarwlA6jzT2YP{#Kw~Q0D)HIBA}%w7$9K=Jo#>m7bKacT!exgFNlpLM}a^uiYrE6 zkV8SD7v0MXVnfLhAkd29ij@#>i&m851+lT@C=h5xam7j~xJN6>@PgP_ViX9{Gx4g3 zC?>c?E6PPi=TIQfid+n^pkOq^dqZt2X66Ao(Xf*H6|>k_a$g|Oi{gs0N64Wd(Tnbl zjABE{5g^ct;)<0JaEn%yi;QAp$x%?&iaaBd^ae?8BNyoexv>Q2P*5IUwAP|BikW## zP81Maa|cq!5v(mGRLum5iX8F-$=IT6qM{r(IOhihdXbBQmfm27L_}KKkM~JZ54or} z$f;(rv0O}0zUM%YM~LSFA`~Q=(Y@T@90CM-QCu-{gPb3@MK8*P1gq0U><0uHeyl21 zLcu+HQARb3PZ>E11bR_iu@VZBu|@YsMzOKvC=lpHt_Scjfzm+IEEqVjHJ*U){8foa z(lsc^MMkl)914ohK0{JR<@svjioq9TQIKdx_eMssq2ve<=tXhG@(36u>2X}ekTUa_ z#m17OpsW{pJ|O4~MoG3C7oi}hnw>*Id5qCoi`rMsMvo`1v9^>@H4`MRamWuO#v^dt7a=>$x%?&i&hmY`GI@J7-b@(bG|?@#>nS;ZluqOd zt{H8%pPYnC%fZjLW^^-u9c?!`31v`LjJzJ_AmA?@Y(XFyUvxJF5=*Tv9b_ONkc(pf zQtAv6x#;#w2dkb-91=(pv~W~lAxIjs6B@JQ_Y$PoP;x&Ykc;Aqu{X&1fm`IF+@*uqSaK8yaxMBqqq#0Y> z&kkZ^$x$FsjN*!wP;iT4l#7gFW64n

    fs;utY|KSxp;tHg&T!Yl~}qLGEUx*jQrK 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�Wlv!qD4aG+x?@MI1 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

  1. IJW)1 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

    xXI5|8cyrg zUFK7I=nodE+^$$K=Ay944Qm)L>Ux*FdjCQw^^w0{%8}CID(hjlDuwuO4Ci8{_b0h_ zZkhI<$P#_sXIdXM_=Ka6sa`4H@4CqNun0cbiuzym#k^ZIiHf z(mJNF?dg%X7LqSy4DAnH@GDB@Ncw=PzpOI8Q9iU!+hg+8LD$KbJKQH*tUX3g^}U!& zN~)(#dQl%8vNAaq*^(TKdY-HazIz0Gm#g{JBjJXto^gpXU!L5?<*?#=Z! z)%%QLNA||Cf~$BZdQswEZ@BAjzgh9jQQG#v|Mvf{EIX8+90y3bag3xsXG#sDWwcNi z)7mDXplI5CcC>4zqeNfF(6GcP>2nLIZE&FnMITLEcbP@hw3=A`nf9xhHF5egtElNU zv5zx_tJyYjk2BNPsKHn`m~MXN9xYYl;`(m^>kCmdZ9_9!uUk2O4Ec{eK%g7Dlw-#@ z8vdyVMd-$l$|uI88vdyVexEz_@ybWWgd6zcA;;2hn|nT$#}oh zvi#)e0Phvyk*7TWBQGf*yYmWYxb#^;!5W560940BtqD?d?_y+vMKgMI(MRaB(}}V4 zsj0Zo#HYtU800^9YEYa-B|!jWz(3kT%bR*QGKRP^I%hQIPhe?79=>Y>c@kBJblmm&*-sbzP{a-Y0LjOC$*?9*Wq^Ejq;*8P!dxiyU*Cj zMbFUNP0#d{i=IKYtDZ@utKO`^rMYvk?m+u5syGkF`ZOcy7Xj>J9QIYVU8=2x0wsL> z#k~B1{E6c$5+`{QIaefd^O>GpWh!}dGWRLY4clUaFf!k!XP&JO`o`GTykS|>%APFG zp3E&!BD_I(B@b6T+YwJ*F4djr7)z1h1k9>pr6fxc&HRMxrdBshj#^?{R=wky2tIV) z^3mFr37MvKs+&^O@=FZzcyF|5zwSHeR=i)ND4eZW$wVbJT&P%S|NeX7hm#^^_XT{G zpD#EZF32>$1$AO%MT@BQtxk@4cQa;Ko0-d1gFC>nXJH8>aoJ>`q5Gm z$##%X)EVGX>(~OZaphZjR6Y%LoWssO>HPV6oYw7omo7eo9eYHUXYxjLiKu~*r)uuu z_K1CzML)~FhtD1>$BK)tNP8!){PWWA$#+h(Z+oykHauzBS+Zawug(=VAzDE*ns~l? z>&d(;EcJ0Po0Th9$!psiF}SMQ2YHqbhgb)7%i{CZakPV@1Jbx{Zr=t1QLS%>eu{^w z{oKA$QPk(UX!RE1jpeRxN%)4M_F&zyYd={{RgFqLds^V{8NI4=8aiddH-){_p7y;y z+#-W_$4zhsj^}?lFdOReQ!OC!nvCj*dUaWxZ5>PX$m(jNEY+GTqO6e!%$$06wK(gK zP#;^Y*E_Sf>N&4ihE2Z3hBY|Vwyb}RW+=4`zoHfR$vr%?%VcwSmhR`G*L|}d@r+l7 zcxvab>*uNWv*$!q-M7)GT;Jucj}40#nytzb$`}aBNc|!VmN{x#)ltI%cd!l5ZWNqg z!+#68-=rfG{^Qx3RwKoU3Bz?^mDh2tS{ojy%?psq}KD{~Dze;;gx%Zu{-JR!W<8Cn8 zhlJW6mK#jIv2HLq;07%D;|l}9Ft9Kf_UL`7TI`2X{meI|m&&cL!n>^`*{dAeKl?V6 zel)T-$t<+gd{X*F%03_0XQfpuuU{CS6cd(w@Lj3J?Fmn9)+45DM_jqaL>l(5&A9h4 z@ETqJHp|TSfiL{==4>SwVz3hCf_w(K{LN+KB6TwfJ;v|REyq^%Z`2KtyI8W{@AlBD z+(VL*y3bj%-HoRkn*6)B85tD~NnzxjJJfj^U;gOdX2yHUyGIrmoD?3`Grz?;>O6bx zqp&6!xBJO%*0?v`tCULrYR}SZkC!iY}}*fcI85S|Mu9 zEUUtnA63amSW5LTTA@n9O3&oI=kx9qNqQe1*syZ&mDK0*&|?_xk$V^2+Dk3VYDgkGPk%~c11;e0t z$uDUr{6~F+Xk=06)YYtz&b?FYvhH4^mAL7k3oGQ^tEL{I6lPWmJ+0b!)(WXGV;G02 z{<68#U6iE&`c^bnfwkU>qnVy1C^@G>bD;Bj|B&mesqh-u&lO=i-l}?S`q8*m_*$W> zie&ie`X5y{*IuZy*241+yPDyP(ln|H^wYB*&1q;OQil9=4pzxZ^k4k+Igb_BYJ~Nc z=r28)Ka?{#Wjw{4JGX}0=xQVS7ej`}e&(yy55!nCS9fOK{_LIq z_QjA%>d(WQ^{a2#e=aq4uFhAQ4KHAeh_{T)@9XDwx%53Yx2Rf|+bl9%*QE(j)0vY# z``(3XOu_Z#H}5=f?7HrwcY)IEw%mtvx*=uXw{3kiCzIG@axSqtdF_q4!DqLsk2tYM zHp*zo)+6USByUzXs$~qpGCF%l*B3s;5294ygs%+ym!ox zx91;lq9M|LzdODicMt2w-oxJ@onnP9#d!UHe_~CKe1m7odvvLfS9km4d+~nMPgFlp zO~ZaUm_Pn=Z}H^hmAXBr=S_>=m^vH1w>UBSF3ru(t@O?z;oM!g#_FiiQ?HJ{Q8j%& z*u_4S7+L$3`SZE6!pWc7Hr8!clz)0#J3+_S}Y50YqLwly3DLr>1%R4pGt8sB(aXV1X z(b|64r|j4*&*N_Nh0r&@zQ~y6y~-&^k^P18zDof)Fe^_>yM%XlYpiEjUKq`<&70d$>wE45l-UDIeyc zpLAeqQ+KgqKZRgsp zVOpG3tq*yp?URQ$h|cg%Ul#h|TQa;@ z#EITTNi&8gCC1GCq^mAvVKRPdH!Pi@`#{WGwz`%{N56Jg6WE)s?HbPtkJ-yjx)bar ztqgqq>9<$(PZu|R-Ih_*C(wWO5@Y!ui^6249jE8{RojflObRbL-4L7a3^_gTtWo_MmTU=^ zrB9kn$95;Ob)ys*#U-q3kA)m&65ldV`}7W9%GJ6ZnB2{oT}Yi>wO{Ml5xV?Nd-O1g zPS?6Tz!}A)m>9q7;%L20akTA*O=W6MG3+C^cNghl;M)`J?6>eI+S@BS+K!wrH00I8 zTu5W81$(FHoG46GDrnxvYdwFfP@RXm7i+aJqeGD!Xx?(nvpBGW=+u6=OTt# zuFC|S*F;-_LqW-4sSEA72K*cbPhl5M>T5@+tT{QcA|dl^ozYWXCieF^qScw4X*+)E zzRBVAYHeak)A*@-JtEtny7@-u>eoa2`U3eUwk3Zbpy_d$W^82KRvVm*9YcL(mTd|X ztKeyX&|1UVfvLiDKf>u;x;JBp=Z{b8%J=y2_{~7u{ccITE@wv9eu;7` zy^$^ziSmmt{Y1NaBO*Sjig0azQgsCB$0%B**Oq-`_b`vns#>kp`%c+U_^9Z{=)tb0 zJsdLP$jV;5ud!EMG>pHx5kECU|Cw>)bIWAM{Q5g@oGjdnZWdd-c_-!WnOH3UAD?!& zuxfpA=k{A#Nm|>{SJs@PlbnUfCatD|QjVqbQ61|ArcB4;q zD<_Ph8~&*WylA~H<>)bnhJWh8IketKiR?lqT9Ue;@y;y>; zxc=k1C)&G~cy{0jIBVvOuVCzvF4+*ICSo$IGV!6d(aHqf_pU@hzFn$4%QR~c9&jN* z?}mC#L7C~1jph@@VX_sEM+bBQ%5->3E)?Yc*yMEW8ut9%(`We&Uuo>I+^x;N#dX~# zX{skb4>hfaK4L^j@3@Z5xx3;*VpYQTV(tqC=~pr%-p`GiMr!@+xbobJUU*{m_~-oS zgzpMU7fP8Fg^Wc@n6?SsuQKcq`si}$hjy@gPUgCbs}-mhFALpGg5Aq9@q;fv=kp{S zmQ~&A9q*64KPcrL?~9xiGVKr=a7j6273_X8(`Ro+1?tVqpf~NKZ_rxZ(gV+|x<%p} z^QFCYFv!RA^N7t#?>H*UD^O2gZvHXve7WCcEGD}G_2}i7o&>%G`RW@YUSk)9Udx9$ z=on%7%XCcob|hI_UX#Dq5`qkF*`{E@%rHM6rxbwGiMJe7C^pf0_Zq)09<1*Jeo0H}6VZ%aWqA3@TugPeyxI;u3WdvaW}{wFw^@4Lra^-XZG3{H*hm#oX~1 z%Ue|jTr97C4sL$8g>Rnup?h5AvIcbWCuQyslkfxE!+?EgWZ=+lF=Db>-p1Z!8^Vz9 zxeYal*S0MUb&2N0lw|4fUzAg+$29C@LbCvj#Ch+JszPY(W?V*5J@X3#sv@@9TI-Y@xlL z$S0BMU)%0L@1Y-s_|%}W2i&>SI1_jc09+qj)KB#blInP}-a6J)WV1VmZD z3405W4LacjNg6tY@ph!~pb?`{2NH3haRKA*Pvc0?fBDvCg0o=isM>=T|X{Yw={nz6tzq1&M5CTzA{C)|5TsfBtfVv^TNvii-0l?u3GH~#< zWkyc%0Bv|?pCCv69MJ`VkSm4UZ`49=ncG7zaeGK4upHpLmP>_P3Dw026aY;i zFf6wqq6MoUX~_bQOPwFs1MHVqFakB%X9MRj8`~(V)mO)Sx1A*0Feu6;3FV{fQ z0V3xM`a$HJ@VpChKe6}#49HKY(_p}V9zfwC#aK{$8b9C}ylI@k>oOUDbFRQdpwA(< zDMqvCS{MBXf?Ri(`j6iThNPq<{a7X#1Pm@C2XuLveh|!`OfcjQ6bVgqzobOr8b~5r zkkV3biXdq$Bqe>otsh~+AUFnKGJ)WoAJ7yrnqA-(GAC(pvlJ-XFY& z&brh5@~;STjb17rB-IH9vDCjVlMfuJD1%a=EkROostYkBv>hR}C=zT1 z_$z9Hrdc_XkuRDL8V3BS{BkWJgcZM}K)CsD6oaHR3yd%Ir$~~jQd11bw~CQXzL2Rn z|6+Nm_gvtY`j{h08n|c^OSwhB5HfNgcwS}`gt&=}TXLU?`j_z~Nd*>|U+OiHBt3+f zHv>UbFksgRjJyXJVd>@GVv%*!Z$eJ$1C3hdCkf^V25fPlVRABZz>t=)PGIjB>xBD) z>lVTZBq^K#n^qA#10kG{C$|X&f_xUkiC?(|!M744(#1q$Y0yd7;fiDx#=!3F3HCs# z1{B+hQrbW2H<1LzUS9;wUn&qJ5+#F1Q4EgCmmRLpg{)m{_1#o7@fnndEj%9$}+os0R=ry&%5?nEp}$AP{mg3Lv0c zrV#`t$uxp|u;nQoAV~m(p(d#aQ5y0~9U$QZNgBHWr;yVpI)7+dAjtrVxLgRX5ehMW zWf}6ncYi1u>XRhcN$uarKn@9Q`$}aJAn^H1285dfs~{@DfjKmmj&_!j~=_FXi7@H}pE!YRj_y7QA?=KPk9HyoxQg8+81e7woE3*^=d zmQIzuh2dXdZ>hHhSWjSI=k zA?46AXc(3BfZ(KljVIy0zr5UH(xgD{<e=J0QvhL=}{oCgB9RT>KW| z=U*|70(3JHfs{T@{x?2Ofuu}}^W8FWfcXvqV(4W%}MHwru1<{_fB%) z3QK();RJ~_9WcZs?*-X3(V=^R;Kqa6;FIg!QkJQEHHBqfZ7Iueu#2-IHEe~z78%P6 zMoh41(nv3;Jc(t3S0kweacI#?y&B=fFaC)@0Tk1i0*)cIUsQUsfEN9GUk3J;rmFks zWxfo6BZL{5r2Ak?Z5cRF#ASm`;O-aagqwrGrp7F3>=&3_>b}4R(?lhOq8SJ=aRvhm z#q};PmC0QjbaKoluG zo0XU%QF8z~;}32Bxg7E(e1SwJaeGpIduQ-KMNMxne}LNhK`=0k_$!1>M4{0KTZ`&A z9(1+W@Fwmq3KNqD5vhWr9CVKb4&lHd5;Voo(a$@;*TK;b{0`B`e<3^IieLVRcz1O# zFR%+Kw3WF(;i-@NT)o`cWYxup?nc7F)!$LZ#oNKf*AX1~!W9)MM@~#u18mt2c1MSH zJ%vFVmV#~G32z`C0C~H?Ca7SmQ!wn{EJ6+i>{dZc9*qRMu%pEg2n7PXA+HE9L>P(! z=2j%Ph2PUEwuDw^-+-Nm>^xHr zge_SYuy}%bQV!>z2-GjY-_P9<>@>fG%)cg0BwSGj003Yvmy-dR91;Pr01%$ZD}cXf z1xh+eHVqBy?}fQ^;1Afl9JKec50HbwkzS4gzV;pzX8RY(MIdDqKvDsb3*v1gh{_Z| z#z~c2^3dqd$#rn?hA8!LwDY3@w1T`r4iHHaEehmS0AQp_E4k15b6Nu-p~^dZ zdpmnL{tZIm@<26#3V>-r9>Ae+1(b|Dh(F~4?tuh>8ilTs&%}RDs7HXemouOh<>=%D zIqyS%i(Cb?j65V)KrfV*z!d@Az;jWhm*j>2n$Eg;hd4TU2f8|hKmv9Q!gzT5E>#A$ zzvK?!z&oK7!RRjtSq=tPEkI67jcB6JC3%Ehz^M~F=`H}Q!eI+>=PqERAWjGV5lqm# zz-U2BeZ)6l7Kg(Yru<#Nh9Rd2K4Fu!_ceDtWaO{zsSj-tO}rNPb?E674n~fUZG zu?yHXv<^r<>cq)pk)Y+9U@z`UEr$k40r*WnfAAm=Pqv_U#TI-0-tSsjHEY(zVtSc{ z$-CVnTiC3^rq2EOw|CFJz}9PRG!;v?i;{R%&{>cjDt7wnfr7kAjTfQczXfu4+X+0Z zO?Do6YKB+fI=sIo{!}DttncGnZdDVDbYtV5;FZ?ajFL~UUX_S3d}NT4So=tR8ubG< zzV*V9NTgNK{`_;wT;7N09&@z6=|&?j=56H4zWsIET95t;Ovm?>BOT*EZ=u>dl54Fy zd_om^y~f|az_{E@J+)@G#aqBTHbD4#u+U8tp_a=l6a?FEr^@?&ESusCe=DS@8>lf= z-Hm>$6D#WdV`TQSjY{{OaCgg$f!vF=Pm{Xy=f7rWG)OWM>B@PT$OfzuJG_5p zF!EO4#@Cakft+WCALwa|tTNc2#pfw|JSW$EI9>maK#WfCy73u&S^$rhg`ql&#d-17 z1^Xqt^3*lYdO6rgDQwm@etnmx@MDrfpX#Nn0^0&L?tbO=?ctI4&{;RVL-F#x)S=Mu zE_T&{iAwkbMg3H*+|buCAnE z#JQ8kt6FE8G24aQ#|z(H(KN+>w_Q>GYs}1JfPxZdKe;<&Y`Pev_Hv3?Y zNrvlVKf}DMk|v!DMaM@aXSQF`K7U;tCLTK9D%Ps49TMZscf;^drMvUDz^GZSs$qC8 zN6wv($^JY!eM1-b*QT!;@;G+Cz(U|46H?couFtWkg|09BQ|yb{_A9ie8pAv1SlX1f zz8W4Bu97?P%vyy02S@gKu^b-ydb?zU_Tb1zohM9odQ}dgJyJj3+F)X=RfYna@!x*= zqbZLC-{G@aXsgoc;(!9ncUn{(x z!Je5slP0ijMOc$g=#KIAj?YGO_R(%L5>w)duejTtuF!2@KGn&4_`&R^?Ir7-pFDL< z6x^rYMC-i2>|~Y{&NI?Q>C^7l&o$j6uIwv4quBn&;-LDlS^ZBOQCR#>t+2u zg_zJcD4t_d(H%%AEFa`(FuZVDBP+fVo*FQk&RAMs)|1$(m;D`mrZ^f~6w`lE(&fsh zo03=eNo-PLT3?9yZuHP~`nz7QrXTE83uhu;$#QZQ<>-A$rU*=6GH?>>vy*uXOk7W(HwYGL@iuKV^_T9bh zgUP0*wn9#ul8$uTi@mv{nEpYWM^dO{Vo>7SV~=T=n>og0-uK@>+?UO1tsgqI%Hf<4 zw)3zoMI)e*6D=j-pH&v@X@Zrb+r_zI`b zTdgOBF*k3O8(K`;{WzT6R&SW!E3j?;lcmI-Z2rD1jYwoW{_gb)dY7yWH}Ae}RPgYP zaL&hoNu$HJau0uvNy0fxBF`RXjXWC3Q!sPAd!3V*P(rkqG-8ExquTHnak;8W4~x;q zoaheao$x!Sm7ZVv*uk3m;wUz)=6%$frXB6wlKwAT*AAU*%zRQd`k*lq|JWT3<2wCw}tcn%+Zdi>M$I;PKh z3Fq&9`ef9S!*fo}WPIQG)EgX<8*{OthU;U~hV<_2c5E~4+E6l*bb#AnNMqz>X1Y3)t4s@`YrJZd>xuu0A2qnX7yo~`wK_r!8Wo`k;G4^&O4{t>lioM_DFG5M&zV~vmI=-Df7tlqpuvu{H=D-W z-oeoCONE2_l39HWb{u1hB&E``{QtZ)2wQh9@OK-undhs)po6lF!zw^{c4yYG^8e){ar z3`(y)cPb@yT;ub>gDK|lm#elJp1N!MMd4@M#xq5#q6dNww{pctelr_Ao3?v>VoaBWL zqBxy#Ej&et@AS`l&!k#^=AG4887lOVLxeR++bn&Gs1IE zem<-TNMYO1$31E-B;*&s1DyoVlhd&Gb0mJEzEe}vTyLwctLK3LKSOU% zU2nyG(uR)C0c^56y&Sv`g5*gIg(j3QK>3QRub;oBi@mRy9C!orn;njR4!*7!fACyC zlp=v)kgh-rh{P`etWwt4+r-Ni{1Wtd8&ai;nd?FDygl&4gk>-CN(^Go^VfJV)HKmC z-nE1W2s8UPJjheyfqODi1(cC# z2x$%Vmxdszh!+hKX+lQ(FGwe@tdNmTls7r)%dw1qr{+6%YpQGQBZwCwYf+66)Wk~! zPXCp77nJ0e3J{4Vr*S!c0YSZfq-A$`Hrc(d;AxkOUV&8p3tuRcgfD>Dq^cHDT?c?z zf5F;B6NO#&4#1pULkN%aqyVS>8gPP?QvgV$oES=8 zQAPm(^hksvC{IujLje>Bg`k9c!9zmH9NwSP?dM`2;^^oLk?kGe?+XO%9pL8?{5PnE zAT{8WP$;yF0$7TIAT@|sl)M6f*eKy&IH53v(uDp5|NXDxs&W9WMuXZA6bwiitcJ@0 zv>FX+!l0r#aGC-PS}gzlYnU2Nj;|1-ROkGGe- zA8>4rKym*jxzHLc5?Z}N%YoG^d7!rnGDuK~N?o?gXR1H(5Wkk(#IHIKWKbznF+a3%F2ebj5g_=_!l0hvEctZAX zNG4BT{#?8m`vCCpTgb=`Iyz$hj(ow2CU}JSFJh6P(gl=#P?s-x!u03FdboN)l>VCG z{tmrJ;Kx8MQu?1cZ4eI~a)f3Wgfj>~ zeL z;0w(w;0^Q%q%wq0fb$~tdh7ym7@W{#10X%h5{BOtDnK^=2Q>+VE*eVnhoBKqegsvc z5g-vFJ%l1KL$QS_NJSzJ1pF&RD+s&@e~1VO2x*~rU?`!#Y(zK#dQbczI3e?e-V>`U z;2`E9exLYbpb>N7J>loT^$WkZ&=3U&>OuJaLeC-4=7skQzekuN!S56CO*S~8w-3Bu zXh|db5a|5^JqrzJP`Mnb@()fb=Kj-SKPYHkEcPReI|Yuqq@!wCi}JsMpD9|ahVS~e|Ky0M$lHbFC#DYe01d}K_GOUZDi|fy*+-0~!-CUhO zB?ZcgLQ^44M+W^mj+JJUH4ns!HyO(iXi`_!aI3*NtJfEBEVSyCcgaIC4F>MWDZLB z(7<-7TuN@8%gF|nc?b~0!>L~j4J>IIqk1jKq^S3w!54et7KeK2P(fYrNYMU4g=X^9 zk?MURNDAa4)UG8D52%V+9u(%v0rIHacbR%ERc!j8gs$jqd3041Z{sgu9wyJ1d+QYkdUmo-T^nL&jV6*ZBHoUBTbIvp~hnSAoMk&^oSiW zi?Kg^q1FIwenFTx;RJz$HW;!l8Gu+opRvgjAqY5WtE2xYbY6%>$zrx;O^Bp5*@a2` zUxm(u#xn9*f#O;@P??VanuQ=#zEd-y#Xdrk%b>U(suh<5ohWi3HCk?dOBxJ8$iJ|b zycm2yc)9}6Xe!tKTknnn?K=tpBcyWeGVe~!OTxiE1aOeVQMsO6Pk(Px%hT#59fW@^ ztp?rlFklKufP|tT^b0KNK|TNpmdcP|!l$q#il)ThQ@GUV|Em}f0t$dYS|kV7^uX`~ zXdGZwz)1mhkO#v;K`%uo*D-EYL+D=dLV*V1eS^di5mFka#u~!^GcM{zk@S$jr7d4_JAzh$bvEp zr;29~g-iw&0E~qaDj+~}g9HOI5+QN@e012w>r~ymM@Q`J|(n5T*SYQT{W=NsPnOqvMH+$Eq9l=^jpQT}@m_Kg$>XL!BT-w!K+6IG zA&o33Xru;|l6C-CBykCaL_nIHLLxFvP9b@8_Gc6t@7CAdXACIZX-+{Qn%YP&#Oc3G z7C1%pL`aOBMskn#XEg3IHq_r^Ku|}DicV0ON=+S!xBNvURR2mrC2`j| zaw>^_ot#Q?B;n7f)HgCTGlU>WLkc31id1MM%~FeFy-XbmPJo<5q9gf5B8cyoObwKK zD3EYG;QOe74swLi)>MGkmu^7saH z;gT^*9E(4p^uHRB!{q@s2xd!&UMNzO2lN8EpsJeX^e*=ke?sqnv2YCzb_Re!i36Y( z+A#(W>g-@3xu#C;a;HI!T(T(qzYyR;1qfiZ6I6deSu#k)AUyynECNI$|A)Qz`Elgf z_WZ^$FbjI+oi_&Z0b{893DwEWj31;R2(GIBp_00~TUD*@*1ZyhY*uy^uUKSVlGWK%Iw65X}EcVwwU+SDnw-ib>a9@)}Ut-Sqz zzbEe%)+|-O*M`Aj>_uc}vUTW&V zUM1vK0>ycK2v-L8Hv~J<##Yd7HhOa=Tf?O>4ebV%I;da0d;cbaSnb3iOk4mnY$#$d z?u4^Asv!)Vc(tMWHB0V(2CZgtm*UvIxtUa}Nw5rVITmezY!oQF+hiHWeb8_QUrWp; zHs#yy{p@3K`M%7UJ5AtlftD8&ctcEtVImKMaQLcVezNJinC|H#yrtBQJ<{E)4gN_jCQ+DBI=C~v(dyjLq0p7X*`cRkGoD@kmtoc(O7 zbYs%VcOB41Ia?-weVc?i4A&0%^1abUmCi`r+NjdAsWzl=K24RB&V+lrUu``52^x|* zKd9Yd!I}pEm{uk$Lfcl#u1o8#h}`(4Asz3$P&5^B9wX)c}h? z?522iPn6x_Z4SYH!NBV}M{!m8MSgt;7M`NFB5u&KB^R&_m^c85tYUzdbRR{xDQve1 zgT;LO9?RMD_fFu8`RoP@O&c<|Lt!Z<2^4x<8cnZwbf+k~K#pz=;b3zl*6@_QTN}3C zf(&igxdAej;^kKsl0H#%iO2hwubxZc3A9lC=2yv0r4P2&Aot4 zb1#|;tPrpE^{)0pPRmBHn%k><45ceqj#zgu5l}OFk3J{8Qnr7X~PNA zg>5+al+%j_lOSm6LgDKcV>`TfH=w07!QouPJ#v3*6KHeJe=9DFi;u5P&R=gVqH0%{ z6>PYys#L(+Lv%}(tg=LxMH!5u(2;6X6i0BH*}YG*L+gqpXkZM;A=X@@Jr@oNMI%2A z8lXND-V}DbR_`NhK-Yh|n%y41e)?v^>8YKf(al9;BpX{|YgSCu!&G2sg?>L8(@oz8 zOvH8So3Pqx?BZADWIus3QQR`8HIs+@u>oAsg+ zYIwrPW;iJ-rIJbrPZ((}nhO6%?Wm?Gz(W`__`;yB$^H!3tO(lH7;|r|ixPj~E?Op* zWU&yK3B=|iFu|}47y6Ovg1ptMzLW0`x~7;^!>9^g2XHZk!#t1% zCf=~!NPn|mjiK;9>f93WF5Q0F)&K=iCIGQXfXnS6>J<7000o-`vm47IS=bB(a)54! zTeA#RDJ*KRpoY>YB-nzgnb+MKGM1=-LzygL$JC!f&rO~WZ+X_F|`SpymMmIm4>F?e;58eKYVg3o>8YKM~V2ztTsV| z#sUspW$9bdKUpK$ShFXIhb~t>YUS9xHg)VuX*($o&%ZhO?g&yIZMqAF+@q?qm{vk= zxJP-kTl1JHhxc_Ex6SVFY4YW(^OsM~MaDPH6`CQh9#=-7rj>{&uMItV++3H@7wEc- zb;}zlXXvGY+{ikR?IHWd`AeY_mCy%~m4$(@bz8OlUhiWlUdgCefzb8-s~hZ>^AoFy z2CPDNJTwrt-lGhL73_yGZRow5wQ_5ML$;6!&QE|ruPfz$q}D@@GjfyG_$w1ESki^o z1YI%AD#-G#M(crDhJ6IAO}Wb6O!$9!@($+mH%^n=wQr1M{c3}z^%*XhVIQDYWvMt3 zVbui2T(bLQCc?u2G=<%-^R?BZxl3D&T@KLE79S#12u%1%rvZLMShOaG%xs_l=hEG@ zPy0-B5XUW2yovzI}x~SQf>drn=y@fGIsW zUIwE;xa!Dq%~Vz+%Pi97_@(3Olbd2WpS?eLv^<=Afql=+7l+4B8#C>@imIGEv|Utj zf{XKQFsSSnPV`dgE&93!GqM(@vQbo>6My@X@Y~gGC2x}5RbH$Olck_CsWk+I7XmZD zkk%NGA=rhcymi~UyC~G`fGY|YScG^mpH45o*qD!NuUc8aW8l})m!TI#l@px|*0v8Z zpVSn!Zp!x;^$$@k=DAR_)~b~uBWhn$-g@(~zr0ts`SkJtTO;2Tb1A;VFCLvfd-|eL zfLqRbBIEm*aglj0C8I{!rO3f!Xd7s*DfNCW*JgpZ9*rim#V;QZidC(9cDPyZ+KP<@ zRDiHX2EFLiyE!h*k{cQHZo2UX*4>0GaIJ};n>6fO?KXj`Oq$HiVUA%#z56v~Tk5@? zEXRxDuPOdDN<#bkHoz>520RoK=1dt>DYIRh1K`Hup#6(4*)nL^+FaU+(lTfm-|cqd zAFn-=FSy;E70U7In4QTRIq{lxNFOwNMDV2Cr==)GWvpPFKJ3%F^kXyzYV zgUEi0LOEPBrO{1P@NvP>p^cg)M^~+gGXaOf=~3@3X6!OdWH>p|;R1=< zkaIsHwW(0@U`8h9HTr-GAX$iQg295@wE#VCgF;!itKxCKk7_HCOXcHq$Jx~F+xh+3 zNiW7nbnj}pyjgq^$Cu;f)$Q8{*iJphmfwrn{M}^sYxyzYKj$amt06 z#I#fvTF`{uxoZWi)+&nYcN7xK^=T%k=v#YSviw zwH+2b0;_a(6A7Q(>fO8T`9HSNLBYcYwHTPlT2su;V^e833ZSi$S(l9oH?$L<)+gM1 zunJHJ)z%EQEW7_?UWjXupPCGW-L`fiCINH1I>+hc;SXOQKiW70NzQRPS>}_deo~Kj ztE}@McrtGBAJK&r+cmeqCa6sS6VPEWsrufBV;N-~XMMD7>E%$J3>_^T{_Hk21SxO}r?ET= z^Ks3V9z&~j*8Ks=fFGf(8A{=i&^8$YIfTe)I39>GRPZyGBS199=9?Xsz}lWq%^9?A z=+Sgwa_}zw6^+SH@wJxWge>^b?sS`t%&6DjKOi%VP#Snbcj$J>qHr|j;&UN+l3`OM zjiz3FF8Uk(X#y_(&@v@co7i_^IBZ|01fZqv)DT&-fYtc$AC<9)%$g42Ip637JBxd_ zHujTM+@kA>2C_@tSoMNsorturRWBHxMH_olWiVfVXm&_4P{p$jrD~N7xbzGq8>(br zz6cvAY-C5>(*FUqLt|??I0q(}JZNpI#5BR;VlEp~vA~L08w<}QnVnM`xDMV+e{6PW zF;&3zIIpC2GSJ!$(P6=uM0PsEF;VbO4v$G1OVW0YN!Ei6h!Xw&UiE%uMYG0jj4!Z{ z6x4_QzH7MTZ`t23mtlJ2BiH>n!k2#e?PlJ3Uj1i{Z3bj!+I7CV%(Thg9ugS3F3+PB zP`|Elfo{bombqlk{i>+}YD4DQV}(&t`_ciwV@%p(A`CVL))y*8LBpIlyeD9Dn(#bp ztfl$`Dyz6~_i;W$hc=+<9?1kBmMmgW;k!pN!6$q2HQE5@!Sn~_hpVl2*zb@Iaas^B zQU&-UP7QKGg)ECfle{sh=3K@8z(nAD3|LN`4LTGmImSyoTV!8Q85oME18k1l7j$!` zt+9UW4=Ge~P)(vbRE||kCVRFEiK|*N5ILaPW}#}VWuqBSH|}ZXvKUWH=~f4Qc+8n&PX(nc0}r z+STSXH?4e({gY)awm0K-OCDGn;8nUhM+6;W7jCC|R+~*`mG|WO91%Hpaii@(?_ond zrQ_`$b4tz?w^EO5cbZ}49Bc7C49%Z3yv?`60(%Z&V&DgkonN>v*oPPO z<=d$Iat_zg@S$2*NK%vLcwV^UdmrY@BD(hw{wUZo8{1RKASKBT`u4Ma|FiozeMX+c z+1>XJFJ^Cx=wvdv#aVdn(($>8e!O>@kH*vGY;pDDeLRi>RDUl<=;7jaRIH+W@$hjp z8NZ$9^N*O?MYDitUXGU&h;^OIO7NerXY=Cci}Aa6;}N_i^v~1cS7)`W&P&6|TD)i> z#rWO0xY$ZqS|vfhY3ouJpkNK3mD8`@0WIhltF@WY!Be}l%p>i zQSAh&!h|GgcxkuF8|*rW-9*|+QiTahQnzaDBpHIDwUwj{6O?3oLUYgD84mgx`pvD% zYZWFaN!_-#(n%kg1K+n+l2l=WlGI0Xtt8PHRJJUzWssm8+Y^I(<_#7{_d$7EX`~7h zl%%Ug#b`~*=5wtislo&$>1hgNYqzV(1q_d61rZsY6eJe?-Fd<0-j?#PD zSZQ`Jf!<1zDojw4&NdeQ+TyF&N|Gu}P?GL87AuzkJz7c9FT(^S>1<=A6AQ-LN|Gu} zP?GL8RwQZJjqR6Vf|7K$vDnKO`#-hQNfjn2NoN~t`uJbVa#Do}O48ZJiW?=|>ROeP zDojw4Z5zAk2Zgid{V-_l3U&VN^KTvc}RKu zEWgIA>QgyrGLrqPzh4M!!F?$}b>vY_idJzRo}3oT922{kwKOGw!89mlZp&Fzxdq<= zZI5+NzuX71%w(h~d$av9clsi8?A5V+< zt75(o2X;AcyqwlvT|(h{c6)s^nT>vl@cnFdJH1%W$2YYH)^oIFjjy!hH7@18cD_-3 zxEOim!#c#r`OVkG`0{EQ$)>ZhJSR5~VD8~&Ims^u)j~G z7Prdv_toM_*$%awzVwRS(1_P;sS&AUVU1u-;7*0CyfyzE#jnQ2uP*Dyms8-%5?+** zuPRGrxjdP^o4IpR&u`x@Ki&v*m@j{w&A|^o0c5Z-rgLa&K4!T zXsKH~r1ISGoVr8(3V2a7$wMm70Y{on@-!S-?vP&r*OhMakjitzN#!o- zBH8D_X3X96Ln_aho!IOocaw)yp55klgmyWw>29ZVxy|($@{r22^R!{eLn_Y!zp8F} zCY9%g*VP^Bd&2|kF7c518v(DZPI_+mUfm&G4fm_N#6#+DG@PC8A`hwm9N1^FTYi!3 zv)dDuU^lShkkVcR{B}C&2NZ@Q56M2mXN4mV$vy`*X6&YCl6`jDs1VAbn{H&pLn_Y! zFNsci4(zAbEgn*Nc8mN8dUg}ZjCe@)Ik10PH$9W=b71$eZt{@IbAU*9lE-a}M96oy ztr8<1l6?;BB-Kqnr1IR@6Y38A9}s*>`_Mrtd$}{};Dd_@mAjQM6&q-j*qAul7 zcKBuFyWfQ7?)4NqRFLH1l;^~4IKxO6sXRA!o#|e`5(mi%>1yowau<0x_8DuxIpwFZ z5zAfDMJmsY4O;FZ4`;qE0qUgKjTI97@=Gk$a%``Y9dpc{P@YMAP!5OY=!aCE-Qs$N zen{mxuro)ud?%G>x48g8KO{bgv)Vc3$8E#JNEfL*llWjl;)Al4F{Pf8_@JD1&5?&> zpGkbsZ~jXtht9=`5f7<6I}amKBO*ChqVq zLVl6>VA9y2;ST*V5+B6+EmD4w$}@=%CXL-1?x1H9ACx0NDeVr455hl|BoC?o9M}V) zlN}@R!6a}}TsL`0{S6Wy#I75hd?)e2#FFOgNPJKZaHG^y5+B3@PLez%`%L14iQ5F5 z&@PksU_#=9IJcIQUnD-5koX`@cOj*VRG!@?=#271vd?b$5c|octp3L7d-A zl80oU-O(|O{34ZS5+B6g$s|2<<~OjKh$4@iIL&C6Q+FuB-Sb^GVC2ZdDbJ}pSeTJ6 zPI*qt%k@1{#k;*fP58_A@PP#~ZFeR-YOi6q&C9NOCDPAN! zlk78z52hqOn3DKlO5%eli4WrB2Ts0|_#jS?BgsQ5&!qK(DTxoJBtDpu_#loY=j0cO z52hqOn3C2HrX)UygX&3oCfR4w`azs@!bum256TH*lztS656Yg`9C=9d8zerMlK7xM zhMh1kLE?ici4Xcib_wYs@j-vcFGC(uc_#5ee@HPST_pQV;)6JBiDNfNd@v>P!IZ=Y zQxYFcNqkVwz@XT95+6)S>j&ku6HdBFY>^VIt894&NueW&_G;)Bi8&>ybLkcTs07dlzIlieV#9}FF>-Ax{neJ1fi zf2J`Z-${JXZ|u&Hhh(2gd@yuMa;Ne`;)5B95BhUt3He3hgBghrW+XnCk@%oLOBtDpt_#h68;`Dz=e9)hVOeoJJKIjj3X2?St50dy`M&g71 zNNa+ANPI9O@xkWl&UYB^koaIm;)5B94`!tGgBghrW+XnCk@#Rn;)5B94`w7jn32{G zW+Xl+C%Q1^jWg2zq8W(~W+XnCk=74pBtDpt)(>W+^@ACS4`!tGgBfXm(Tv0gGZG*4 z$Da}U2_!z4k@%pTdQP!FBtDpt_+UojgBghrW+XnCk=74pBt95AY_7}vk0PxfRHXHT zinM-Ek@go=BtED}`->{l`awn7UsRFS4=U37K}A|Ws7QQJk=73?(*B}~#0M3L4=U37 zK}A|Ws7QQJk@%n@@j*peKd4B2P?6RTD$@EvMOr_oNPJL{)( zMOr_oNb3g`i4Q8${-TP+2Nj7AD$@Cbio^#Mi4Q6gA50sTBJn{*;)9CB z2Nj7ADiR-5BtED}d{B}2pdzgwR3tvANc)Q_()vL~;)9CB2Nh}kpd#@>MdE{sw0=;L z_@E;3K}F(&io^#Mi4Q6gA5@j*l4gNDQh4T%pL5+5`qK4?gM(2)3`A@M;&;)9072Mvi28WJBgBtB?J ze9(~ipds-=L*j#m#0L$D4;m65G>v)w$Fu1&`tr*tevIL7;<{L8(N|wZ@r(IvbY3i@ zKjZ7e$5H&U_^^zA>cwxKzx_)wD#Ki-k>B3&3=v#s_#u1Wx(L4ds#i=eWSf}81c<~=mX zTxi+5Mc!L`X?+{ahls9}10mo1@F%3zMpoMg156W7Zzq%Jr)KE-W>kUD%09?YV3R@e zppS{UPz?2L0ynhz6J)6A@#I=Vb@Ik-)zvrIK0c4)hsFExs5pCa6vZdeyL_^M8o#Z+ z;Qq^bK3&|1szx81DXMQvd^|7m<#;xIm@kXy-or0&Xu0jflP2l+@&ALq{jA^r?0zqH z&&}r1y+dSW5uHpXw~OUGU*gj7xru(fcbbpJ)8%Y&_2Yd!emcAOy%?d1i`!ALic$*K zWc+rX&p#qh9`qAL^K!hLK&*V4-(1b+`OkCY^yF6L{drpadcTpZ26cFvFP4yD{BB%a z>`s;x?(us`InKJ3Le?xe0sipl!}7`bQbNRsC+C&6k4~fb*=&BDPf(H%qa=!-zo_m# ze{mWmz4-hvTF!3~?EExe{34G}@ne+B!?T<6;d-eJK#RRz-f#1AJRE-c_DMbaz5GF9 zu$(4a%g}==pa7(Mmje2$Fkw-)H+SAslwm&^LW`@s*hiEqOjwkpFB5(#twgE91VstJt9=Wtk^i+5rC){#i?V&b-kzc)SVN6j!&X|U!h}WH z-r{XfQHH}b0l04^N);w7N@rU;#7?5{MQA5V873@BXItBsVyoJTQiTbN(%se$aL{*4 z6W1@pghlCWZLuSdINi3&pejsQljGWcoPjZDfgVNp8USsa8kXgifrg$aw&+0rKH9KfxxRZ*$JghlCWX%m^2Y-wq$ zFkw-;TUwbvXemm+3=1=6-0|?Wydr*Z5 ziV|>?+SAhZC3{*nKUJ8pD4lJsmC;?xs$7K$i_+cJ%Ir?d`jeDl!lHDxwH8ygZD%E` zFkw+T+gdb*2Cnk0Y;6@LEJ|lviy;RVy|$913=$Tkv!%seF>MP<86+%7XFDs*vTg0D z!h}WXZfRv2qh;qBd%d|ZVNp6;+C)a*Eqjtxn4l;D7rs3$Z6@7=mRhO8ghlCWX$_R! zb|6-T35(L%()NLWu>81PO)kTPMd@s5`_gA>*(z6I!lHDyv;xIiHic;!CM?RfrFDK= z@%ioB<;NR%l)QwKi3iR{`J(VQ&;Io2;dc)|Kb(*A$-&WVa&h{y7eAVg;2$%+jN;eh z>EU!SUSD`To-dZiSNS}GV^b_~JS-NY`S?b>ec&l0rR1y^i;s?;)+$(ZE1BmqTLq1L2f}b2V)HeOm67MPT!NPS<6k z#hWr8PmB4hV!nX0T$G@KmL7boOK8KM-CiF}W}{ysd_SArPA`_Ibue9SW z%trBy4;Lfx%fw(9Ht#sU`MMZiUM(Yw^#t%%^fwQ1x@RwbJjpK?E9-LPy*v-ZF~qpxbGaP{?VSWUU(So==xXh(Cl_Cr zQsR~I$uggeM~Bl(cpc*B`Leiv6=A#yZ`U$0vdLIOE!*vsL|QYLYqemV&~CM)dZ${j z&i^0-#VOT-X!cQyR4J4_k!D*hr!W1T4UKrsmKu?B?7|w6nVOvnsai|;3%?o{zq+g+ zUryn;Te<<4m9HvGWw|_=zMDD!<5g33IA8uco5NS~6TYX3dC(U(&}N=&4+A=!zXvh5 zjZC+Aw!7fn;@R#$cZ#RsDeJ3pw|KUDuHE9E5W;tqco{cQKvy2(Q- z&z$`^(v-752jU@>=YWf2Cp~la=RgOZRGvBebI5=KO+jUD?@*pO`*T1ZQhDa=&jEQz z_L;LkN16tl$U2p0&i)*bhg6<9`*T1ZQhDa=&jEQz<(acT2jn4@XU_f{a9fa3Cc*x2 z_UC{+r1H$!p9Auc$}?ww4#-0)&z$`^AP=cLbN1&*GmMKExIpgfl0sU~w zbH>@91M+anbH>@91M+anbH>@9Bh3QXxl4Z|n_UC{+r1H$!p9Auc$}?ww4#-0)&z$`^AP=cLbN1&*GtT}T zh=@fAM$YK>oU&%{ctoPm1oZW{g8)L zo;myXLmpCj=Iq}Oc}V4%vwuJ2A(dy&{{8UfA(iLGzCPXOd$ID8Gd^`J{_gWX8E5}~ z=$X{tAn`%*;iAkZaQ5#{{k}?s{0i)!)2SaG*b1jxJf!l>*}orpCfR4s{{4`LWS>cV zFeCB7jKl{s5+9Vc^_2Qf;)5B94`w7jC>}r@{gBEti4SHZKA4gCU`FDD8Ho>OBtDpt z_+UojgBghrW+Xm{Wx<^KMdE`Qi4SHZK8Rg!IQk*+!HmQQGZG)nNPI9O@xhG52Qv~M z6u(JE`=v;HP;vI}PZfy|DiR-5BtED}d{B}2pd#@>MdE{s#0OMdE{s#0M3L4=NHLR3tu# z%?vo@hr|aJi4Q6gA5kC%8`e}2Nj7ADiR-5BtED}d{B}2pd#@>MdE{s#0M2={h%W8K}F(& zigUhqsz`iLk@z6?3+31!5+9V^2`ToO#0RmRB}X0-A5MdE{s#0M3L56VWI6#Go#gV_9(BM*rWDiR-5 zBtD2Ob4mK)_#-J2A5HHi;u z5+9V~W+>&5#0NEr4{8!0)FeKrNqkU~_@E~7L7a3zDnFe5hHTA6DbFN6s7ZWKllY(< zMaIz&r@x^|d{C44peFG_P2z*H^*bfMNPJL}_@E~7K~3U=n#2d?pfXN=k@_1XKB!52 zP?PweCh@j*l4gNDQh z4T%pL5+5|A^@E1Q2Mvi28WJBgBtB?Je9(~A4;m65G$cMK2Ov}IDv1vo5+5`qK4?gM z(2)3`A@M;&;)9072MuZcpds-=L*j#m#0L$D4;m65G$cM~NPN(c_@E*2K||t$hQtRA zi4PhQA2cLBXh?j}koce>@j*l4gNDQh4Qc(LA@M;&;)9072Mvi28WJBgBtB?Je9(~i zpds-=L*j$(gki!tP=>?@4T%pL5+5`qK4?gM(2)3`A@M;&;)9072Mvi28WJBgBtB?J ze9(~ipds-=L*j#mw0_W#_@E*2K||t$hQtRAi4PhQA2cLBXh?j}koce>@j*l4gNDQh z4T%pL5+5`qK4?jN(31F|CGkN^;)9mN2Q7&YS`r_$BtB?Ke9)5kpe6A^OIkl@Nqo?f z_@E{6K}+I;mc$1wi4R&5AG9PsXi0p~lK7w{@j*-CgOj4_Xo*v?M-gNqo?f_@E{6 zK}+I;mc$1wi4R&5AG9PsXi0p~lK7w{@j*-CgOj4_Xo*v?M-gNqo?f_@E{6K}+I;mc$1wi4WQaFL*JZ zjn0c@^yesk@$hl{`N1$Xc>L^WfY%Wn<#Vrle6fnukim~F})C%`P4RO!SQ(% zKP=vlN5$EbBLs`y<&#Ab#otz6aR22zpDu3lc`+S*Y{pdI|L1sKM>(Y=RX zr2PaFr^&EC#JcP3pl?6x_dmPei`{dxd35g(@)Xg@WOBP$&hsTM9iN-%$9t#wXgpoc z7FR#s$K$87i{Fb8nz*qizS2@zZ(}9Tj@%xbRiSwfPd>AEB{QO0A@A-?|J8XV?x(wG*WZ6BcFru$O&BNrtk-sAUHEFkw-)_Z!($ z6dWlgz1LQvRAIuRY;TdarzqHsbBK;dD^aR2VNvQ<)}P|Orzo(!1F)-BqEunRqSOsz zD^dD=oTiz!6Qv3h7Nw&_6&rz#B}_|E$}nM3w(aZV*>nj*b^CVt@dn2ECG53V*HOMG z{LPae-W+}Z>hr_-IG-FG%_bM8FMIK$=?G2D^fHQHkEe&z#dv+;@p!&i9$)422-BXi z#PP6LjOODTX*tp8NHsp|#nN24r;-$H#q06K@@j!TLh5{rWWU+%|1vlKS-cwn*TJ@5IN>%Hm*1!492K?vxx^tCWDXt$?3bU*1lqWu=e1zypDA{b-{l#~YWc3}j zGId}`J_nGqx+8!4C|Oxg!mh&Ly9Y^fbt5CT8`$T^PtdEJE(_EL6jHIOXXvuz*XWEr z%|D{kmfVlx?-%){>p6+3tM{DB&Q!J5^YG-fSmx*t<`E9j7Gs3S4o}eGD|=sZE0KF5 zI`kbTs<_!*O6hq2zv)_K`{#4aOSsmdE+^ zc=8b)c`;$=W4mkPNdYAfoGS>FCD&YT$3c51x6haJVmZ26_j~2y>rzU*GCo=6lkwsL{dLE<-MVr0kHhFZ2e5)x_6V6N2yr;OcdN%c;(plf=NfjpLKK{WfQ zrK|v9wVb~63fs_#*KDZ~IaD~T5qR6}R!G&I!D#W-xcJp&{rGYk{Zx%nP?qZbjIvyw zOyAAicyiU09nP1(&gK|)d}17zmC^(o;gl5kcU*BIZiZ?hh(2QPBf5*WS==sH0VxCSFzb;>tx3`PBf5* zRG!@+l94V_dFD9LKtH7N%yFWDJf!l>aiYmGjuQ>y*`9~&R4+JAG?0hX-{3gWKps+m zgX2U4c}V>YjuQ>!A@w&nPBdA@aiT#yB>T*9qJcal`^<5ofjlJp%yFWDJS6+faiT%< zMe1*GoM<2qsXTL>Xdn-%Jae3AAP=cLbDU@(52-wJoM^I)<3xjaNc|0t6Ak1c^*1<9 zG?0hX-{3gWKps+mgR{sU@{sx)oJIB+7Ldv_XOTVRA(dy&B74X~D$krn_K=5Eo;i!` zArGlMa~9cW8E26_;vw}n8g6rUm^bDuvPZf|<(ad{9`caNGiQ-KlLJ zkLeapc~+c7_K=6ue^#7D_K=6ue^#7D_K=6ue^#7D_LycPm1hzkR3tvAIE(C|A5wYd zEV73@r1DJSgNnol6^Rcj5+76~KB!21P?7kcBJn{*;)9CB2Nj7ADiR-5BtED}d{B}2 zpd#@>MdE{sv&bHJhtq#nBtED}d{B}2pd#@>MdE{s#0M3L4=NHLR3tvANPJL{_@E;3 zK}F(&io^#Mi4Q6gA5MdE{s#0M3L4=NHLR3tvANPJL{_@E;3K}F(& zio^#Mi4Q6gA5>`h%Ep}@o@N{ChyAJim1s7ZWKllY(}@j*@EgPOz#HHi;u5+B5_ zO`P&f;)9yR2Q`TgY7!sRBtED~d{C44peFG_P2z)^#0NEr4{8!0)FeKrNqkU~_@E~7 zK~3U=n#2b+i4STLAJim1s7ZWKllY(}@j*@EgPOz#{VrE`U$?GFd{C44peFG_P2z)^ z#0RmNETOYhCpeFG_P2z)^#0NEr4{8!0)FeKr zNqkU~_@E~7K~3U=n#2b+i4STLAM`tF654kXAJim1s7ZWKllY(}@j*@EgPOz#HHi;u z5+BqgKB!52P?PweChrx5+5`qK4?gM(2)3`A@M;&;)9072Mvi28WJBgBtB?J ze9(~ipds-=L*j#m#0L$D4;m65G$cM~NPN(c_@E*2K||t$hQtRAi4PhQA2cLBXh`b^ z4T%pL5+5`qK4?gM(2)3`A@M;&;)9072Mvi28WJCLCsPsju{R_>Xh`b^4T%pL5+5`q zK4?gM(2)3`A@M;&;)9072Mvi28WJBgBtB?Je9(~ipds-=Ls~y*NPJL^rlia#koce> z@j*l4gNDQh4T%pL5+5`qK4?gM(2)3`A@M;&;)9072Mvi2S`r_$BtB?Ke9)5kpe6A^ zoJCKutCqwEEr}0W5+AfAK4?jN(2~{j4_Xo* zv?M-gNqo?f_@E{6K}+I;mc$1wi4R&5AG9PsXi0p~lK7w{@j*-CgOj4_eatK}+I; zmc$1wi4R&5AG9PsXi0p~lK7w{@j*-CgOj4-Oi<;PGs_jK2IbiXWr8Bo5h}MPGdt z#V_Ww(Rs0q{*12=A4l=a;=?lfsTaR_{`N1$s0?$hB7a=^86vpW_#tZ-Tm)Zz)hnhK zGTn&-PPcd3e34%kQGATI7t`e;!ZWgqCZahlF2?!M>;qmbp=6bi~=mXB(zJDytnq!`gRi!5nU+K(}&wJDEg3HAB}IVFW^} z!Gi%ZHW{W5h8U29VyGWSwxP|RAVW=$C)XCLljLrzt`5JB&!hNZ@qRoi&Ym1a@k#V9 zpDdupZ>ul3|8kyB7dN7+(Z^bT%|UgXR1Z2B-?7SX+jU!?s6oGlq9{XXVF4*K@9 ze*d%kz1TfBn@9H!k(EVsGMU^imh*gxOULIX`tjarJ{nJ#v&Geq_wo4Y?Be%ggeER- zN5v{iDO{8B+j&0!h&*}FPwpcPznQ4|*_BW8 z#S#*X-;Ill-HDQ-J$^6g#>qXBM;pavdsWDz56dU#O9>Glo}5>@K01x!XS4ZrK0!G? zjFKpR{-V0~{KaXM^y2fwXgR+{u=CS=@ryh@#g9=g56^DOhZ|*fd#jASUfyr>ay%S- zd4QMf_wolxhX2(R(1R+V0Hk}D0{W{kVNtfX)ZJH1tgc^l=z9uzf30sxU!O0xWM&s{)nC%EeZqRAIuRbhfoBNo3Npl_*u1uqd5v zEg-$@qtr^2Doj|E&bBrI5CBxXFkw-;TU%*RTGk-x zB1o99DBZ2Cl9{h|#kOCD35pW%&)L`7V%*VoW<|y-5+*E4XKS0F=LCn7R+YI56Bebj zwM~ZjUt3YiFkw+TTid?$_FER)Doj|E&ej%ggu}Lj)GAC^l+M<6AhU2S?Mf9UEJ|l< zJCsSDmYswuOjwl8)^>n~8A~Hu)u1X&Sd`Azc7Q!9+G2((Ojwl8);57s;0W1DD^-}F zC;{)WeXVVK%J3=35O6=+QxGw=aIR^klPXMDC!K9Ah}#hBhFXbIg$aw&+13uES#B#z z873@BXItAxAFgFhE`x*x>1=7y|B>Zkt+J;I6BebjrR|G(YneS&n6N0FEv>WpEwxgG z35(L%(khvyZ&{VAFkw+TTiR3x9xb~~RhXbC0l&sQ4P0M(?k&+v6(%f7=YB0JG8_@w z)u1X&Sd`ATwvV0)_84eYnX52iQ99e&RPaShQK~RuQMPTZ^Jt6DZ{IFI-oV@DB^+=( z0YAzYg}?duPtU)3boBY*e4I}Xj%JgK)0e&Y(R2jgq3LB5zaCEyr;G9W!sGFLu{^%Y z=MmOC#uCTFVlkSJZ^RD@UPNNt&U&%96vvJiQ zYt?wN*Z8%1zKYjx$Q^#Byt;~E9sBy*I;4-ue~K4PKN9)eZx@4vX}ZY;d}CYce{ajH-FNI|6E^p`=qTD*N-ZNc|UM@PM-Lb@)4pZq2#1-_ZQzq zlGS%`l+^7SEuRC(S>2JpPWe3vy9$HveigY~-N=aT2KM>!6Zi-^2TLiW($<{82Q9yb zYu(fQBV6#r*Y5j;cw*wdWOv;auJn$p7OWqhoEFO*-hFwb25yN6B0D^R`(EizC$|#0 z=U&v?x|hm5|B|hH8Sc3bHnMUvP9^um4hP<+<(?SEKsY1!q;?^k_?hP8X)%9Q%olKb zj1pAP(zkJS2@S`y+v}srZ1hWn?`N~y>BSP2y!OD_SFfz~m3F*^*(jdz;bJ5ns~A_H zB{SIbCtZh#-Bzj*-j(Tg8X@=N%!roMe~arBV;QQAj_yJ+A!DsOq5 zUymmr;g%^T433xX+IUikl1ryXcg^K?9JF^5o;e7e)Yz{xtPk7}f=0RUvWE*)B=uthH&u(wpxezNjP(y{4n7+t& zi)Xtp(=DFuj!3t7wtErX;@KW>b&F@)n0Je3yDoN%rz*m-P~a~4zCFn3BoAk$h{`xC zMGz0EJablxKps+g=IkT~c}V4%vy&X;A(dy&PI5}x6^30^oSoz#52rjU&Q5ZWhf|&v zXD2zx!zs@~u{rt9DbK30GOW9uSAq3jUF?EfYXD2ztLn_alo#Y@7sXTLb zl7l>?^32&uPN~4ks7~dXvy&X;A=zinPI8ckRGv9I$w3}cdFJdS2YE>4nX{9eQi0Vc zoys$3CppMND$i~*_3qEetB6=x?o$V2LHaCVY|Je=_$I%J%F0%s>Vg$hrS zhcmwcfk^U@$}?vtIV6izo;f?oK^{_h4){@bvd^5I?8+yNcNetlN{tB*=Np9a*&7Af9C8Y2YE>4nX{7| znjKPqBjC!{sa|k)l0&*k_Sq3gf<5HyB!_g7$}?vtImkmQ&zzm)u!4nDo=JRAadwhJ zx=7`jvy&X;A@w&nJIO&FQvaE=lN{tB^`A+6P?7kcBJn{*;)9CB2Nj7ADiR-5BtED} zd{B}2pm=*RI1x6-A;rV#KWh>n)FeKrNqkU~_@E~7LCra7$}JYBltU69)FeKrNqkU~ z_@E~7K~3U=n#2b+i4STL9~9R`N_i&nK~3U=n#2cXg$YMLocRq+;)9yR2Q`TgY7!rm zy}l^+bX6n#2b+i4STL zAJim1s7ZWKllY(}@j*@EgPOz#HHi<(#y=E$NaBN<#0NEr4{8!0)FeJAJ1kT3i^K;t zi4STLAJim1s7ZWKllY(}@j*@EgPOz#HHi=UmE(l=ox}$T#;)9072Mvi28WJBgBtB?Je9(~ipds-= zL*j#SegmaEllY(^tsgWbK4?gMP)_XN=$T}nNqo?d_@E*2K||t$hQtRAi4PhQA2cLB zXh?j}koce>@j*l4gNDQh4T%pL5+5`qJ}8G>QS2d!4;m65G$cM~NPN(c_@E*2K||t$ zhQtRAi4PhQA2g)(gNDQh4T%pL5+5`qK4?gM(2)3`A@M;&;)9072XP1h$Ig@Zpds-= zIop8Jev$Z~A@M;&;)9072Mvi28WJBgBtB?Je9(~ipds-=L*j#m#0L$D56WQ~l=@Cu zKWIpNP!2ukq>D7aLE?jk#0L$D4;m65G$cM~NPN(c_@E*2K||t$hQtRAi4PhQAG9Ps zXi0p~lK7w{@j*-CgE(WBVplDR4_Xo*w50Wemc$1wi4R)R`aw(LgOj4_Xo*v?M<0<HoH@74{C`XY|$`6STS`r_$BtB?K>jy1~4_Xo* zv?M-gNqo?f_@E{6K}+I;mc$1wi4R&5AG9PsXi0p~lK7w{@j*-CgE#}7W1mTU(31F| zCGkN^;)9mN2Q7&YS`r_`anYReL*j#$#0M>j4_Xo*v?M-gNqo?f_@E{6K{=X|($6IE zK}+I;mc$1wi4R&5AG9PsXi0p~lK7w{@j*-CgOj4_Xo*v?M-gNqo?f_@E`NAG9PsXi0p~lK7w{@j*-CgOw`koe$$#0Li?J~$xp!2yX64oG}(K;nY~5+59p_~3xV2M46}g98#D9FX|nfW!v} zBtAGG@xcL!4-QCta6saN0}>w`koe$$#0Li?J~$xp!2yX64oG}(K;nY~5+59p_~3xV z2L~iRI3V%C0f`R|NPKWW;)4Sc9~_YQ;DE#j2P8f?Ao0Ngi4P7)d~iVGg98#D9FX|n zfW!v}BtAGG@xcL!4-QCta6saN0}>w`koe$$#0Li?J~(Lbf*14I=)71)e~#i84GZ~sz^meH4AM)Aq@Aj+JbIg7sf3jgmF(+fc;YS5qs$LCS}uy{Wn6=zS55G;C^ zPZmWKe_MUQ{g?B6y12>b#dP$s8B={d(eb>W?-kDtyielJF7 z;^KBxtfCZkOvZ2L`TS#)^dIySMDudIoItF6xr83Z)61Wiv!Abu{388%TKsyynX0mQT)?5+Xi4Ij@v`bQ;Ca zX7lTO62-@dQ4+<^UsU&=zc`JOUVMHSE$6ogc7B>Kev!wg_%X`m;n_|3aO36M&dPhe zyx->KcsTs>?G;t~z5KyY4KZ!HN`DXEkbWe4SNi)^kgy=zTh8n&2r3K)9_=J4!-PfI zUUj>#C^!)Vec^VZlwpFR1i;UpqF^t(A%@|tM5)4rMcMXM*;5plmmy~ATZvMI35&Ar zzO|<)XAVL|Hl_2tJKRP;Rs>BIJeTD6j-3KJHkZWP;zl3In1b30MWFkw+T zT2mMZ?2rQ1&`OjlOjwkzw)H_@_d(5CNm2$03)0=rf+~TxwvuF6h6#((+0rKcWQZxRhTT!Yo zVNp8UT4axGeb6d{sxVVe_JZ0 z3KJA1fXnx^wF8V;TPmdt5*DPhrA0M1@Iq*pJ!P1%D4i|sFvI^^b|tGYVNp6;+P=yX zFqd{(DZ_+C>1=5e2m(yoN|Y*0Sd`9|7TZ@OZCm9kOjwl8mKHNzvZ+)ntyE#cqI9;j z31|=eU0R7!g$aw&+16$%N#MHPN|Y*0Sd{LzR(fzP?aHtW6BH%j%CV=dO)x-hsgyEE zSdh-P78O}e9&DFAWtgxioo%fQ+Tmo=N|Y*0Sd`ATb|?m}rLC>PghlCWYx`)G;dAJqq|KH7;=h6#((-PX#qSIZU%q|b#3i_+QF4rOH3Qj{u8Sd`ATwvQPe z;JS7hRE7zQ(%IJbrL)p=tem$NZP8Z|#g~#LhVtIU(&m)-tkvJX}i_v_1 zBZLNcL+Z|1FBUN3o=Q?siPz(c<<$Z#Ds_AL_3_O1f9OYUT=geOHlFM?eyyIb;`L`> zgr6y|u3}inzW%lj>0|PrnOjLA^10tG1_|?19pelG?pZDMzqjh)VG>Zi*osf9UXoC$ zYMs>jH-EU7|6E@;vh;AJxPDYA%rCu?=j4e`DIXzv5=vvH%l*Z7k!1B9UDVV$TFR%m zmQ{D;Z$Ew2Kl8?v^PXHE6&L_7LxhK62WXa~eRPKqC zfpAE<_Y@6;Q*uul%0M_R_sZJ0`9A2~dubxvF{*4no)+_0#e4xE8zrcqC3Rh0!i3_p z+v}srZ1hWn?`N~y>BSP2y!OBvB9^tj(vG(<8D_d@#9H;xma13qodge7>)z!m&*Mp?IXioG+^5DmdE+^c=8dzSWFmLuDdp# z6i&%yPRliy+i}p|$?fyyyjYH|)`V3qzAmN2E8~-8J{gY=rIG+!C(^~~Zz#?pPsqdRZz#?pPsqdRZz#?pPsqdRZ>Rtn=v1CL zi#)Y*!|}WK=M`s>C*&d7XU-x|$V0NvoJF3Hhh(2Qi#$PyNd1k#EMlj6!CB;qbdl^c zXOSo5A=zinB2UOevd^4Fo{)!RpE-*>v9yEK-{36rggm73%vt0Kc}V4%v&a+jkjgV> zktgIKm1oW(Pc6RclyN0zktgIKm1oW(Psl?m&yM;K`eU3$o=6v|zrk7LsTF6DC*mQM zXU-x|$U`d6oJF3Hhg6<9i##C@$v$&7frUII`^?z{Rx8dXu!x5=U&q-57V?nBgPcuZ zArEOh$k_xI@{sH^XA@YgZXk^Z8;iQTb0XDP)_s?FNcNet2`uzXvd^4NU?C65K65sK zl~p#J{wj$NDiR-5BtED}d{B}2pd#@>MdE{s#0M3L4=NHL6t6MHI8KxJpeFG_P2z)^ z#0NEr4{8!0)FeKrNqi9NygB8N#0NEr4{8!0)FeKrNqkU~_@E~7K~3U=n#2di1(IS{ zNqkU~_@E~7K~3U=n#2b+i4STLAJim1s7ZWKRzXwBGl>ss5+BqgKB!52P?PweCh#-(VUX{&m=ymNqkUtDxug_5+BqgKB!52P?PweCh@j>jbN76IN zK9l&MA@M;&;)9072Mvi28WJBgBtB?Je9(~ipdqavG$cM~NPN(c_@E)JA2cLBXh`b^ z4T%pL()vLhp~A7xr1gV_#0L$D4;m65G$cM~NPN(c_@E*2K|@+UXh?j}koce>@j*l4 zgNDQh4T%pL5+5`qK4?gMP|oMe0A3_@E*2K||t$hQtRA zi4PhQAH<0}obp5BgNDQh4T%pL5+5`qK4?jN(31F|CGkN^;)9mN2XR~nrC!Lvu8ela zlK7w{tsk@`K4?jN(2~{j4_Xo*v?M-gNqo?f_@E{6K}+I;mc$1wi4R&5AG9PsXi0p~ zlK7w{@j*-CgOj4_Xo*v?M-g zN$UqKi4R&5AG9PsXi0p~lK7w{@j*-CgOw`koe$$ z#0Li?J~$xp!2yX64oG}(K;nY~5+59p_~3xV2L~iRI3V%C0f`R|NPKWW;)4Sc9~_YQ z;DE#j2LWF2XgZo*jHj2q_~H27yJB8UN5ukX&!eja}l#or=7cVl)UpWa=p0Cm--{l?E-!g4Ze)%r{QO0*pLLh7X!=sHkq}Uge4YXGsU%UW;=@ zs~}mDJaDNC^H1L#*id;a?{(;M%ocEXg@rw?=_d$V94iU$^-7N0iN_{52E50Gn+ z!XU5v4~7jnt5wK_e^CyalQeH6gjFy8>k;QPwxOGVF`&SODI`;RK?lL_=Psha2jw z9AuE4dVtV4lI1}bC1MK(_=?inPvtWkB2ui+K_u}0$0NqNSDFmh2g*E1q^@m5zAj^! zVL~ja`}E(Xly83XzqdYn^(#rgR&DAxKKZ>7#rBgfQuk56x4sHtT~%IRsXe^DSTFVK ztMaXUe+u*EZeXQ~=+k`;2BKB}Dd#O<_eUwa?$bXZulL$5KWlpQ@5IPXvRfNy8M{p5 zJLX_fq_9)8TBy?V0C?=?dKLkE$!Kc%RM z3NoiC|LKcTd8aft^2=X`>Bjr(HFs^&Wb?Lt{&}-lexkV=Kz*u*t#767xleZ`8W^d& z=(^$hAnS{^1_`tX2#4=*MZ)K>uTV9HNQ25mtCAH8za@*{tSzeVyFYjY5sGQST$n`Y zz7LF;0IXhqFzm^gc>tq@TIXJzB)<4~Dcq;8vR-m*iG#fH-;wHGJyo)eri;`WO60Y? zz!e!-5!e+JA8BsgRTs_~Wk?JQgXYRL8$*}`FUqGhQs`(o1LDGa zUHK>drnXkN1pnt-LD6hJA`76Ex`DdWAUir;E zk-3tZxgzYdrGD32C~tTCXRR6{4c_nU&nOTE^7v1UVymM8C`5+p0x4ai?7#baTc5qH zE77hiWt=`{_lY<4G>RhngYHw_JV2F($$}jfb0>}G0R4spS#6~@W>#wBK(gIE*;6oj z2#+fnBv)uBB|T+^`N$+%AKbkl6+0nYPq^q|O;Q?8?*@VKN8%SlB>fR-?*=f>3YHSR{n}@eIGa=c!3lU038Y5e!8F3eAx&ry zP?~W?r6}o=)AH$?F?70|@fLI7`CTp|A*wBUZzzQ538G!br?d1KY%4O#ItipG z_Qc-9+F~NyKP_9r%JC=ut#S>rD(T~4lRRiuT5##uxt0hWI1Lp_c43P_$T~=+Rg>@; zREnovfogVbpa+-}Z#LX#(AL)N?&kMeSZ~)|4Bj@nXQ4@HPsJumHwSL!ka>X8A{EnR zsB4d<$wYyLt~0c=L&*cki^8a+Pk-hSi#e93z6rLt0)FAL8z?* zNwu%!LuWumBPcH3^5d=y3#Cn~f4UBz(~5FdAIEG+o}m6qNpLZ`9u|&GmFuVn_=K(S z`IzB7$OW{8(v=grQWz!V1%{3?&_Nuot-&Ey$eYrPBL8q5wFqs!v_Cy;y$d=0lW?bZ zr9`TULQ18A$Vj1H2G^q=-$oBHC$jz~ze4{oPLSrRY}Q>x!(+YBqr0w^QIvnmr+Uq+ z_4u22YQY*edT_09IV_)zJJm0FQwB9iuh%8QH+k-}hu)ZEZTUwUEiC!LqyE!B>4h2~ zZ(t1FXC=IU_YnCC%ZAbfO^R`X1|^sL@M&P3DMTYErqC5UtWv?FGM0h{p-Z#}uJ|Sj zB|VjDCejY!%YdSQ=x{-LBuO99qWwWH9_vbQ0bUBQgkZ7~NYaM7;!N%Ub_o&z`qt7K z`0nH{HHa;f#R6=7*0Ti1bK$lAGef%2Cz7I2_V&Cs{PX^?qZq>NW4w-`%`Z{_;T^ zx2nODH&~4xStC&9`pD%ac(uU>x=$En*M^mU#2{lYCfxO({>f4uX#T~(xlh-Rb@G%F z4AH5QhF(S)m>h$Jl%6WOm}sb_V=i{pph4HL0x~|3_|Z{7L!b5r=(wQ?@Wb^ClaDaQ zu7fLcZ7|lbg6QJn$`ErQ7&xFO25XOTFA{;*4tiL&g?mVyG`{jKbYF~gGsG~YnF{G(O6Oqf)AiWB9_oEyU;5m2bZn$o?+3H~yT25nAbCZGSe=z-qj3#IcM%X4dos>xbB`jBl)`ZU#}zvxL?r&j5lGv-K3DT zf|wA&lz#Ps)s#G5Q3mMki5pgtR&lxBv&HaNdeL~#5DSbjz+K^k>N^JJG5~S^WEx+d zmEV#;^cx+9aKEeP1OWgk$bE@J{<(xyKjel8QECpkCZoF=Z$MztoJ3M-&}js}D{ad? z`3~h^RD;ei!n?m!7-0^0M|Dr$?ViDN5@$U>Ytv^E6aFQogp%~?jS^caqx1ZgdzEzZ zjLTc(=jMMBE`hIJmA?vHzmi0hty18=CFZ<)P4kwyN=`6ksrk#mT3jG_h6 zew8(n21##~Gmrrjk*K-y9PYt>tnO9MNm%(V_p5Ly2Gw^*l_V{d-Y}S3<*vvfX|Mm4 zXDfXmjFVq}OL);ub+7vC^aQzF8YS29Pvj`?d#WV*miOSVKVM98rFxUR-4)1sl>UM? zJ$XvfUC&1eA^$S;t0a(nSRNeW1rBfFy9j|mu0E_^R=q?1ib(QTLW+BR3Kv&*A6Zph z!{45g=j56^TRtz(VYYEqEZlXtWXN?tdh~xGrmvBZrplh`uO!Q5KeA4;ulgtNuKn8? z-l-XKRq<{9m0|&TR$#AETlH7oU45_rm8`7&`}7!FiZ#-_`L9-?0}B@(&!)?V#bPuc z-z;a~$cKwjFf zmy1aCVu}3dX!Ze)0tZ;cdN2elOfpOf4X`x!Cp?JzkH?cjCY_{Qo%tZo@@w?z56{0j z`R?fRc1TDH-_EOtD-2(Ma*}58uCdc_t}-vzcI|-zV1%Id-OZ zdt}rpy)M(mw_?wP>N26JSVgST+DNE04~>Mre0Bcv$+=4?hE?^9U8fU^m3QZB)zMy$ z0C%JlvpltI?bi$O;uh{D;`^~IJ}m1AmGcdDlwnCI*oU}P$lN11c%u-z1uM;ze*NOv z)0ar;qc?EG2&NRX$m@h+y0%e(s}}fo6S`G^vwB(|#oxxy;^*;;_`CR3{5sC#d~$P@ z$8Y1e#WIga-q$9+h>N(mS&ZQwlf;+tRXmP=i6`--SS;e}cpA^*o3if5H{*C7FT68O zyo_(-U*iw)$N0DV@DK_a1Fxsb7{CPhs?o<{v>8rk^x<=KmG zzH@2B%*>87Vp+lNGBuW#&r$yH$bTDC_ltzF+1aREkNUgMeb3 zMXYE37yquksHRamdH<;L-d9=H?Y{Z4hQ-#b(_Dt-vX!8vW&xR)TPqrTWP8=fxpqXefRwE z$>~Fv%Ar8rxn9dKTl;*g0J!Lu-&O7*-PIe6t`MeLVVfyWXW*l0p&pa zboVO(=<$`RkrA5omm8e|xB9JNPrmu?+cz(siE1`%=1Mgdo~}C!z#S}Ry>GQD04;_F z*eRqe?C|Rhlmcfu>w}@w7f((O#i*QZSk84)Khcd0ENI(N)3I1uz8+6+(KWoCEXOyKj~nB{cn-JXQ9ju-_o0#@2B-;!OXymQ2WEYI=+^c% za{t-+^Vd(lfl7kI!^#A}tn4fSfpvAA)RHeS4jwOl!EoX#zQ`{xi+TA69`O6MGD-%= z7*}8_TztSb#uaYTrC}8weSLiR{YVrOdiwtouq7Y(C;7p@0HXSMo` z%2rPP_)bza-owoO0lby5x&RW1_x?s+ZgmyEd-(G8@srO_&yP-bw(gCp4X$4wI0u$I z?#N1+>Z>O%N$M641LdXbGr1)re^bgkI3k5TK4ilY7UpK>Nb z^j+_lRyG@8WXGVyEfVu%lfSN3cdeGAt=C!kZ(i_b>2d4JHij~*HBYrg zTd~w_H^$lO1%=;izJg`FlF~$D#9Oq@9GXVRWDvfmW-|Dz+_nYsI2CGXj#?mSMeJZ9GOoH<$Qgh>5b_2Q1g@d z+RUluaPz%PKW+^+&;SNoqyz~(NHHl0=K@(!wv`cEQ#2WWqD=~jv=j2T;bb%n zY^eGCb~(X7eibKrMvuqy#WIqjfP(fE9XL=u_oFTwM$2p2o{q1_OA+JV!`bNIe3{QN zVSaBkUKS4?9zA{W#a~c+r}<=oY@g5LKV8jkk6%B1lbHKbx}_LzhE3d3`LpQW*Y9St zmm5+<}@-n;^NN@a`gB;MV+xD)C;aNU8`nW8n zrChzlZPr%ZeVbohgO zrEY&Wipo`i$jwDj+*GRg1+TcyMM?QZejU(9JxJmKn&xxzse0q5Rn~&kl7kF^^#iP?_PhW`AoVh4V++SwD74K%h zjz_!!2$wY;a&k(+v06n{TV>x1yL!5@)x|IU1JP?PBsVprv|PVbyEtZ}M9##g{02 z!AweM?cZ=yEa$WL2ai@ME7RpibLBHwRxS~k+l4C?(luI_#6>Zk&c~xGQF3KxQn%e~ zrN3RNK(+Rb#fFN+Mpcw=qW~@D36rzLO|8+M1Wg!KpuGq!xFIR8#94)CN9YzY{*R|Rgx68#Z7|zVa49bMS z`qr;vlg;I91~&+~S1&`&G^B33-K{cI?{jP@=(nreDl?Pp3zwPq-id~?62w_g&-#AmZD3TrNix76n1~WtK8Ain<~K({&inZAlpDL@ zA%CHdXUaa?`jwg6Sz|LxTynQ%_VGYXK0IWvOT4-(Gb&D7{t6z;s;1mu@hK=Z?JuFg zAptT2Sjmgmz(2Qk0r3dClqZ@s%ymF_NQ+l_VTS=>MUJwg=^v8rm)l~d5&{)3b$i`c z7c8u)+f=){Fu)U)fpST~i&D4U)|Qy{`OS4XUx*!_P5)L(<-OI9jT*nY?n+*%-ql4> zmG3pyVt~3*w;d-+#Og_;SVkC5%d3l0cq-MeE<%8;RK5v z`ZHP8d#s*C%9`nt8tzf%Dn2O!z67i;Aw^X$u!;$9EgSj`$-{k}Di~6HZ*lv!`U%hM zp!5&$Tv-fPLLkj04QR$7x#fyEvY;NbWSAd4HLts>Qsz$md4<~HpWjH4L>|bCdRS8#`W|*R`YKO>}+P$d^DbiO1&pdLm^Hk@RdN-uFnY9 z>dabZtT;phm(s)jM9SP#ZZl8R+nPjJ;)JYo<<3jAju?yYBtmzBM;WMj6Yq7$S4jQB zo#su+$+D!bWJ~?yo7OAbKk%W}Y1=4_tJ`VS-}hJWUfD9kRd9a=0W-`e1aw<(cgsP& z9+pz$i#Nvj;;SXT`0fI}_^iSg-w!|?U+2x%czjoXX;TmNc5*F_AK~FuK2iAM%NrKT z`b6Q2S2VtOksIQ;e!-5uQdNKdR_b)KX1P9fRkK#olyw7ds#H-9s&K`t0$;qu4IxUK z^0yDfIIgl~!pRI< zKKXeQ1oL{1pWhVIL)Us?3kfM^s`sx4I*4?ydx+LkH-`A(8jn-fvGY?J5BeO*VXJ7oNWDzFtY1Z@(&B5ACa(+|Yhs1;?db=*yG# z``f9-rQKa(XkQnJrQLmNXkV&%X$RYe_I|2oXp*u^JEP0A`+53$XqOHU+8u<`?z3x1 zK5^!XNoRkLJ0as>*-oF)?qGiKb#ux3v)6B%O}op`2`y_wVsqyH(v{0sHL3jG*Q-#& z_p7q%(#}*fw5}_5^Y%{%S8k$C4u3y?PkoN``TN^hzown!{nE0Yx%RW3(XyVgJ(w{( zq*9l5ci?IF_4>=uzH0L=E$iyLAjte4i&gk?pQe9qa+w2D)plQozh__694wC?l^f?r zWb~#&$IijqN5}T|^N`i>{TcoDokO7QzAAmrx1ZVj-`{>8=A3rFue$k@_T$@`jfVF9 zZoW%9d*#sH4h9abdQFzi-I1okmr;3@nvZn+K;aB&$sg}Jlm;V6}}2HhR5f} zUAO1kuUCGC_Pgu;H|4b7{{Av8Jii6e!^1SEFTcNDDVlG;(Bgx}s3>miNdF7dd{+4fj^3D!uTzbhfMd^rVoUWDPCtNq!( zw+p=aBhCM-a<}vR_Vy7y$!>M8Jn3tRdMcp?Od|dq(}O zCyj&h{pY!JpY!6e# zJgBGN;pGV*&b&JXvVXFGHHP06muw=U?;lxJVQz5P(^aAo=9K7V}s-3k8{ zLGl>yk8eMM*Zf@83v_TV2hX>k!GF+N?p9m^(Yua?dtvzxzxRz%K>d;jO`ly;c1}6s zVk>~MUwnIoq5jC@e(%fT_6NRb4(i?Kq?^0sk2kA)f6rzp?dw&W;qiOqhOdcv@-+wV zZ_%fY%g(`%ADsiSozLGp9`7%H@5|};?B5TnW5@Q+eH$7O655Y5UOs>C{UiAAhoTUx zV|8!NT66G8Ap3hCFV;BN)OO#4L4JI^m_J6Z^jXn}%-_d**TF~c_MA{TSH-cN4g5JT zmP^(P6_&nO;+bcaBD0>=+6_%9oXoTBo3VL}w=@U!_L=D`<4`nc_1_OieAbXcKe6jbLmNI|zc*e#}@$8E|^Lw%K(cWVNKs)#BvoF72 z$W4{Jw!51D`|VdH{KxNswvmx-8BFv3t$Wb<5t{;79L&n{l{@h}BiXJE*V^a^@#5$eHpk0%Ya(4ixS>RcJ6+*;RaGZvCmsx9eGn)2wl{ z+(TKua=xK;o{4C&vf|mn5lWf{@4BW0i@v{Kg`wvfg6?0?J}$ZVxvt)WV?nNu@>QRI z*Y5krxARdwe~&IsU)1@}oGMRT+I#0-C7jHanpH1oxu?8;^ejUQw)J$tV6$&;5PvY7 zQ$KeXwa9Yklu8sVuk>vDtZr-O0Aww#_xN`@J8N83q0IfSub0uDGV=J}bI-tzKY4Oi zmb^RZi-(R%Q!*~!*2nVx`Sp7IvoD|ZDX|t;=lr%cA3XHgW#~!!t{$!$-qX%LnzQE{ zt)a@>v)#uJVtbxj-#(Za=dQ*J_F=_5zeW2B>HFi@zR?l8&%e<*Yey2>^L=&1ZNZ!i zN+0L^RikC}nz7;Wl<&=pLamQJA8qI5i5B!k{d2KMpF#ee7pLXQ=<`El_|7RaYt97)rE|VP zz|oz|IUSq0(e#;#B7L@c(`N_Q>S8tO=X^6)F3;sryUK?KsUK?q$voc=E~P zXdiROKHBH_L^vuPGtYTB+S-ecw&(QGK4<-*Ig+1!KH85tFORl&*rQ!>?wgkXwa?KQ zuS)|=((dQr?ECijoR?^(>M7r&-8)pnm%D8Au698BwgV{hd!9|o@4-H$DWkr>_whD+ zRsTNT=WIOM>eHi9l>2+k=yUeiSZn+D?N0@!_gl4B^LxKoztWC@H?+k9e#--z`IdDg z-+rzQ^uB$ucDbkXt>b9VWIN_wT79l7kZWn4Nf>*lvf6A_`+H2KbM{=j#d>I5K-)iB za&+vq^CHyrPm$ZX_h|R_J$u>}dwh`B&INsc@6Ca}G+7b5HhwXfv%hj(6{C7JUkBM4y7x(Whq`$?s8D>5Gc+rF}+kcnf%9PQJZe_|<-E zrpCs2?JoWEx!>53$2Xy!_>G-=Ph_<(-=X0By*Fmd&^C4f54#~eWEAbXC!y#K;)ve( zWH#Hi!IjXyFaqpa`*bX%FP>5f4M5$!3Q3L4!`KvXUYUO~gQS1nh1&IJ1x45KRz$zB z(hN4km$J*;Qyk&pC6M$5^a+iBCgTudvuCYk-+4yNnzR=(_x3{O^!Lw>?YDzw)|Djk z>=~hS!C}xw_Al2?_U~{0l<@ezc3}4##i6&)zvcAiTh{BH13NHlNHophXFS{pckXcr zR&lImo=s`?xhrvSlgQ?=v*P={aau>~xgcP8?sVEY7t-e!=K=^kb~E2P7xJxTkoj{i zWbT~{t2ZFH_T^XimK%0uN#TbF6>Hc!t@#KDuX}H1unylpY*MBA>TR|M(1d^aSy&_)E|9{_TIiY7xH_~ zh0vS}v){Nc*9MO-^^$L$3;CA8IQ?@jWW3IW{GM|mzvqrv+QyRTpVIf?>#5gSYhFF& zAzT@Or~Nj1oV)h>>X(bmTRe%jv8(#`%TqqfS59E&<-8(k7riS0Eq6cZgSq>m#V3rG zyC2%x(ioO3!0n3}$U5-WP1eE1(at$|mjB4e6=M8b___v+-ay+}FzuKzN7tdTV9orA z(Hz^RZ!N3v__2QCYxfZuk=mY(E_n=W%a_qI{Syb3{<;39FH9}@y)zIkkB_xe>$6wc z(vC}{w2$a3A#&NPJY(6bM6`I)p|Eio`eLdwURT}HHV(zN9=lCD0AcqpHM#hTQPe>* zb9FI`a}K)T2o6ZQjT00PXoKutV7iGuV0PR)1hipeE)U+>l{w0u-JCtp_kK&lrSU?h z9l#q}{B(CSh|UJD+CLB}d^rii_oFfrBe!>=Qygdlx! z-3kwehRnT7dwvhRip+og-g^(NaYfpm=RUD52GK5eHME||Kx<{rFCJL}UCS2;$@-(} z_CEa;-n8>_2iKmLUx&bqjgrk=S&~^VHvis<8D76-y;$VYrxwTfXU=GwyPvl<1XgYT z5O*C2?b$ntZ@-fAA6Sou-Ftv=A6sO3ynp08zp$WPSKc`pf0S|1<10&%Go1tRFKOp- z)yN36P5<~vSO0Mvc$-L`Yr-8pq5Ss$)tzkXBWs0|b?Hc+&UtMaX5dgbeC&^|N!q<^lLyPm}m zRBqyEcWv-&=Ztq_%30TVeh8x|+(uoaoVcj|9PhR_oaPtT0Ldxkl2?FZEES2?1GzNd!%%!|~yJy&^a+h+#A-A7K<><{4}(Zz02(Zy#<+i|c;MPEVunP2cz zPQq*!d0d*!?o|(vM;39v4m+U2JJYul-^R$~f49RvxrzY(cU#bD!or&K*KzclHPKWcD<8AHDX=rrGsk zIY$@&avWv;*hMoo4(hi1j9znVT;H~<#yt-CJX83Nqq9kO{m!g)oKO2LM^4tCyrQfZ zK7wt>cbt3K`HtIeb3(pZEj(t^m&-re{_!10Kl2?23$S`;&p?hjdz>ii4;3`rJB}o* z;1`fJ=Ovd-=3b zrY0*7xM}s8?25`msMW6V-wwxJr=qW-$9dkPcZGaLN4V!*dVKnHNb|;j8RN+I=K$T}q*=_x43-#jXQ4 z=fy}4fW$7KC1wmQ=M38Bxsr#A-tHMk`&?_jbx{rv^YWC(wYwM2{W9b17-|PVXB@Uscu?b+D=;iPfY!{_fzj;? zHC`S9bJLFFrL@XiNsjVZ-^7h~^8>zUkvY3%VnO`ZD9S7Rrx+?~?zS*N~?CKXS z`J&xNH$=4jdHEU%F{uWn?H7MY*@dF5e8N9H^`k@=Od%3R&SHS!g$9GRm< z=4azxnbW%2=Wa~d=V+DrErs;ut2XjOw_jO^j6>zsj6=1Tm1cw7OUYC z-NvO^LtLNb!SbDN*Ef6LZVcMdTKh>#NM(Lesmnt|VaCB-k#SrRmwfwHnR88)$J&ha znTN1E7SmiiR{ii5h#cD5WAEF~%A8#)<8W&V4@fpV4(Tl4#DL@bE}|ywm?J}5JO6#V zIn`gZ?sI0Y@@Q^2A4_E(zsvDZY-9WPK~a`gnM>HsTuD35TyeyfN9#{shDsy(_j-wdPa_K%7 z@0fAGwi(A6eYby%xtS}r>x@G(PkFq+aAGRU;{}FG?ufN3F{V6TU^scW;}EW#xq@xWqZm#^bY<=+E01D0kp`8y7tuP7VmN8}mHB1V?HpXzRB4qt zmr~^6_{})jv&*9xPC7(op1L^XA;hLUis6LdR_1KxnJZynF4xNZ0v>m~Y^50oY@2Z~4QH-| zoJ1a=S$P!0L1C3Sdu(|W!(IAic@)Em2dT{Yz{7*lBjeDO@VKHTJAW617Fsc!bfL zD24-LD|0o7JC0&Fh^8`E`Xu9kZ8HvWJmC?4t+}#HGmhj0U%O&BwCeV=^zZsROG9YI zaF9x6&duI&6vLf~J3ORmX0Be;Wc$VM93BD?G7issmB$MV2iry-LTAe31%{&z%Hsuw zON|*al1I8cgs^0vUpVmcXk3*HK-hN2ffkuV43YV{63U|(&eDy{h3-e@O0h<_-{Vf@ zQ4Du!?->XGe&&jcd1Zd?kMNNEy6ehSGBURXBXe%z=yu-t$Q&*E{9@2Lj$%0OnabSq z=s1eusEEp38cXI%oLlDVtr$+Z+??lVmAO2d@~9o|+)NqARhSz6LakNis=|~f~*%aYh3@0YAGFJ+?<0yu^kk9fchC6p& z#v!sGJYd_*l{DAz;C9YjNrozqVmKk&mAR5r)qZsZ0On3kT8Ha;4<9JbHUm9O!Zt0dsF`Vq$ z>UNtU<2X;#?q3$H@+gK=VxcluM>sqL`i6(?79L{lGgq)}=1O6v@_2#a#G94J3k(O_ zmd6VWCvLOjc!A**AnG`Z;Y>?(J6dEeBPlY!6t?AYvC}&awYVbl-`|SiE<|MK3N5%(X!7~ z>4?mQKxUtdGq234&yJ%QjtiqQzv3c0S88GI{!l?T`4IVc*X(SmPdW5Ds^_BgK*_h3@7KJG8aG@dAxY{Mv33b zT*2#%1GddLF7bHxjNquOD_zbw#LSjQF`S%`%3S(ec@)DbN7j7~+jbnqaF=6J9>s81 z$1vl7ZNr1ZEOW*A6dsohx^t>PaCsENU9H6OD2BUG$?_cmO(?D_bz*a43fd zY@4}qFqFp&3`dET#|sQ6b*VgFU^sQqI*u0@?vk9I>lusU6JKD+|Z84mH3AV${S$R`9YV%@f)2&hQF41P|J;(xA zb@?&(-<+1odsikV_5YNF*>^X+;ptf2zDN_Eb$UU~g7=5-)x+CwJtCMsgQuJ0B;!`Z z{Nwk&+gZW8x7#*H(doN=zHhy7n%~=euxlr=GVM%jXj=>9zLkZacEM}fZ7o*ciY0!^ z?P!eB`+K%Rcz8PQInVd)*4R4QuUTtH+Z=K(?#JZM+%cbsfI7 z>!EpcGQYR=9`4(`9fxKa?YEqFnHNr_^zVujyFBgrIb~5vqb{Zx$MupIV zht4!IIeYkC@^!uybr)J}xxURC^~@?;51zKCOjd69{NS!Nv{Be$MkfnoFTR`f{|rgB@-4xPk+~%5zN~%~LD$d-pch zb6&2Uz=v&jlNH+9Uwqrz1XsO%bdGlHKF@V?MGE*@eqp1Mh58UVBX zbHZny<)LMs<(F+e3ZA=tgBA~6-abox*j#gE=^&?>Kjo>nE`)Y@cL`0j#(t~Z>&ll) zF7wRtF!qv5*yCi`-(&V!`MRBNy%DAK7O(j|N-XnCA*9bX*RBI6_vSV`DE7XJ2a{X+ ztTXAex_;?P-s1Fof_l?V(W&&=*`0Y7jI(P}EwioN;fj-bzG$3iJNJh!LQB0CmNY?& zX}9=KV2{hjwi5?Gcg|~B8P4F>eVeP?X&aj5M5bb-LleBv(O2U`WvDE z_U&N(gNt|Fiwzyy*R@+e1RBBZJ`!gcJ#MC=$5|&UbJ!{GNET(z?$Nwr`)sc+Gw5ZcJSp7i+b1 zz@;9!xdzN#&F`tpwDaOf&RmHz%K7VrpL?F)W4&2jqSR1yqTU5dv0Miii<7B5PV3Ct zVBL+(!HAskm%N#|N^YNVP>Or@uuA3ZVI|xe-M+PowtwOyvJN~r)^?^a-?|(u%?%{; z%mG&#G>~so|L>}S&Rvb+P~DmBpQ9%{t}AKB-n8qP?>KvbuQ$5${Ixq*G)d&kZyMam zqMtj7aNzRLz3_<7&>W~$yz78^nLF_rS@&)7qoqzXTJIH(>GH64SC%XzSqI7rjV%LT z2W#e@D>~yluwXW52z}E|(^tde)z^ zA9)iAEp=;M%kr)uT51uZxm_*aTf9SKGm3nfJob&(tAe)o8OTgv`2HR@;*Jd(k9=9L zBH!=I=H>V9CE4ZS*~rk8$;!9MyJOE%y)tv)xvZ5NGgsCSbTIZ)zo+)%oNs78-abR4 zX=lZhmV1w~DY>VhaT+cUxklm3?;IY)k@*wGlQ~dAJm0#%WuEz&@_Sd%a{I?Tw6r@e zm#-*=waG9a2uhgWV@lgPvx@L}VQAZZckK)rTV!5Xxw03oRQt}A z(lJ@5D#h-3#2c`FQ?=z?_cMQR=jtov>-N6ItkONr)3){|hN|3k(Y!{o^P&!J=J}Gy zw_V@LW5G)eVziC-FfCDc!U#CLebwiVMF~8>-qQxNE zxs`0Y#6ViiYAfwty{9Tl%UiH2hA7swJgD)~RFp|OD0pcYmlpd5^BOBpzO~Vp_Rgam z+Ix9;XeIsgXvwZCGgTg}_2EIs=Jz0-{N5E!+Wx_!ySEHCx=9p3c`(4__ZTzsdu+&| zf$fpo71iGU$z@#KbXVB?o?zJg9vgCg&r^-1{SJ>SkF@Jqcw%^5>B{{*T(dtE(ku@q znH?LL7~N!9txbVuS|2W~O97@Y6ij&7z!{rR$(}@x+GlNZXduG= z9_QG~QbbI!8Sh(g6VqJIeUZOwZ$E2s_OD$T{31FwI81ow-jii*Zyc1l=M&D{Gq7cB z;CleeK@2f^zP&jO^RmSL!O*k;=(Dzj!C`b&SqU(n+LBw zgYn25bc_!3PEzg$!dZjcResMrQ}Ay411!nlk`G~# zD_^iUn2^>DzM|UqzV8u)*p|>@TSAL%iHjw+rHfLH9=~n0>+~EJ83%XS>JlhBXSbCW z?9IU2d4|0+&xWyQiW4O`M`?%h015N0fa*OL7*@iA@ga91N9fw6ltFXxp7rd)x^{H8 z>7JJ^VZp34V)hJm6?_li=e%TE%2@`q28TKJ*H(I7gX|eMjm)#<5-hJwTjp5`VCI>M zjcw$VXXY<4@2n9vb=uh=i@DUf3%(+x;1Wwb*aws7CUxJ|=F8}v_pQ*nFU{22;k1kY z{8(h~Uzv`K&C^qv16SDHmogAKUgoRaTaL2eVo~}T@0rZEFIPKjf6uh!PDkrz?J60v zu_?;oZ7vGGwm8exL;Q&AXSx^Mf{P*QtPQ^we897qbBid04_JnS5AOY=JuB}0qs)t( z>eWO1h{3ENL+*{g9GEL}e#FT9QbyaZ`)5>tnFUWW1?Bwpnpbc;*fjd@VjDLulHBsX%eC9L z8qwgA=R6;6-}E`!;>4pRFXm{2pRZl=V$e3;=h`*)m&IuAZ`W?)jL=#q`e<|ZT)T~L zI@;a`zi6Ywj<)d|M@wD|+QzV4yFEXSmb@6W~7lYQk7+1B?vA%WRf1W)@ zTg-5@)dxpg`|cO5GKU?@qj@nj;`kfy_Z()AeRQ4-|GXbOI*R8xar0L@TOgJ8X&I0-uG>Co1Ny1MYW@$!=rVg zwcA*Y`!>1FXvu9pT4gTSB{H}5Ggqw>?e~(~jF#MHwDsp*pOf2sVMfvI%;OUWZw6W? z`e>0kpKD}(d4Vf)w8;F8A8h4uAtyUm!v7+3wCHvvjpzPx<4A6^NXg_jA1(V_cK6ty z{a))tA1yK$jTxD{enjRqK9c zO=aFX(b_d<@A6?I^VW&>Z802LW!^f`zAc73-+Sh&b)tP+49D{n42M>kw@$Q8Sq#U^ zUYWzTs}to3SLU3W8Asw($W7i(_F(HoYgY_+F5&VhhI4i9K8I~Hj@F6({l**?9<39t zUFy@I6~l31M7N83sLa8f><`YT%vI||<68_T%%l6fb)p4=tuKL$S|=K<819}X&s>3K z8HcRujH7j;@hFBvtIS&`+PB4UXq9>5kd0TwUdEv-8At0x`?eU4slGCAooL^tJ`LLX z?XQ2uaA@7`HuY)His6)C%3TeuG6&lu4`$$u zqjjS3Erw%(s?1v_+PB4URCdqv)`@1ZOnsW8b)PfNWgM_=^cDMQ&ZyRj#-kX{ky4qr zPPA`};kcP9b6YF&kjqM(c@&d!PPPBF}FdRQgdAz`I%-J2s z3k=sf(E?72;m{&;M|Wh-g%O#fMdo6+qT7{D2!<055}99&*UIBU{dQeJ0+BgdWX_Zp znS&saxr~9x94#^zt&)BIqjjQz=VCZ9Xu)tICL;55k?z_>i_F2M>~p2tqT89 zit;FiSLU#7WS-ax!21F%XRo4F=B*R$+uGr{-zsworaX$_ z?g{SQgJ?O=owSvC>qL7gw01bO%Di==eOnACcCa#!Pu-lhPBdEWaA=jew2sUbQ&84b z>qN5(q{bjxF`Uu#l$EtB6}0219qvc#MB`fwCyb{uZ=GnTM==~) zW!^f`zAc91Itz9u3k9u{xRMm_lwG;4dooKXTIJC+5}TMXv}=ss_qXn_I6aMV@zdFw>`wir%WX=To#9C;)* zfIM0!8m$cLnWJT&)3DL)7oWZIkXaR(qebSz zc!J?XRz&8il0@cL=Wb=rj1-wWej{_V>~mT&=lR8thezu~v*;JYi7JS07Xg%gjuzd{ ztsC7AGF0Ztdq3|&F&s@-nYT`~+gmZ5bhXMnv0(VNPV~_#^VW&ht{6_{aAn>)(Y~!6 zPDQNB{1SI|&$LdoU0w{w#2DR<7TgZ5RpzY|jYsWp@2wMk8mBUEooMZf;bg>B<_>|? ziA<&4=dBYhmAiI0l_$E-TPOO`z`M^|CtAB=xGM*hJ=i+YzAc7BtIS&`+PB4ULZ~Y9 z#LQavtrLw_I~-c~dFw>`wsttft!|h88@&s{Wv)~-ip*Ol8sFOCgilttw@$Qgi{Y5j zEA!Tg7A;i_hgO-lPPA`};m|7ci@@K#FB&^@)jH95)R*eY)P3GM(Y~!6P9=fr_ST7Z zkkt-{R+$T$%{W>o+V9nuYG+lq3slWqSsLY04ENqT(fAg_UAldEv`(~QM#XThq1ElJ z6MYr@Ds#&@;}8Uy{n0wneyfLM~%$CiIQHdhlcUSeA|H3wB)zrORGmrios2yiI=h@esfpzB^af&Z69QFY0_cE;|l^o6mXnd(=Vr z8rrUVF4CF5`*v%jpgDS;vA;*#8XrenTd50)7`bQvj>how81K=NhfC9K{H}I#*PpuS zXnS@aEw!YC!6!%TD>VKobKg=!&wYM0rm5}oMG%GdK03#@Onq%9_-MYpx*t1N>VAyO zjp7Ep-`>ZerTzv1tzGX5u>HF4@m#^KB{)t75e6PS+zLmkSG*Rm5%URCSPL^G0$?3XhMl;VB=eF}_NzOf4 zQ6{#GmG8xoZU4lF?U@20?fL8X1oo|b#ad-gUkp{-rH=nSd762?ZM1Xhl-YcU%Rb6_ z78kTTm54=0!!-%(JbZd3Ma~IuIi=XQSU^A5Z^~ zcKwOLi0(X7M*8wg!pqJ9+i=?9ynCOPoby-z?v?BPJ!Lx5XWsJg6_XmiQU#YUpZeA& z_&l@9&MDt^bSIy6bSD)X-N~PvJ$*jmU4Kg2WlyVVl0D5Wxp}E745p4I+S<~rTR*t- z_e0o7X&ezV_fXE}V~aRRjnzvL%f7@S=eb#~JOG&Vg&%D97GKuZ2ylynYPQeG4=@L& zKJsOjiaaE%=J(uT)0Zp8x_n(ZcMtM^N2p&CyvAD*ed_6? z_F1axu9pkJ&3J9h)rm6Uqf6Xyawgw92>Ct7e#RSn@fBIz_jb^(a_GwK3S5MiTB5#{ z(Z20k3z&6H^lIAe+e!Mu{*vEwM3n|f?C3%hoWVrzPufQ24w!kl7!|AC`}aZ{+^v)TJO^rdcOM{%IUhY7k1A$-l8Xe*$XQ- zCVD_C?1D@g7YL=>4bTLh20bw{s3{9A)g z34`@Z8k=)r*A+KT&Zu9Gnce5Ejk!y5_het5@p|QZWrTNaTp8EQ>5FrLwJzs^RUdt& zG*x+62&*Tdoaj!LhwS|et6E*GY`*TxxON-I`&3PzSL%E4;~PtzCf zsMTRt=VaH$)j26GHRBX;p*%dk-76BXYlEvJ>xI`Ucv2!?_P#4qWXa_k4B`mQo%4dH zSH7k+HW}qqvya?NqhADJlm~ZNc(|DD`a1_#X{k@cfySA?@&IF3=9WS1Vcf*I!#bg& zUwCkXU$~RY8_{GwVPGpg(j0h=n;EKIEg4K5QhGV+vUbsaF3v%VANwK*c2A?_E{V1=9Ui0d>6~wz8hLvFjiY`0EM#Zank}8XBwB2n zXz?GR<*gJ}>eP`#^579R#$>|xYZY8IlgKyUxL7qrV= z5*l}}+iwBN%(J~P`_i{w|JiSOSTirqg~-ymFlU~NU(SV7#cQuai|_N0)Se4yPLS!J zP~G(9JE8A5uFPk@wPg19IE8m?dc60+J3iKqc_-eU9}XUuh~>d=5FXBjoo80+t#9T6 z!OOS52P5s=U+Ubh-E)8JI#By*?Gdz9>Rn%C{GNFtiZ=F$bk88R{qy`*Y2B+VuZuAq zzZ<`Xhs${63nOK`#Yimmn;+%(l)1|~a1qFy9;n{2rH+l?vlr4odm%I{X7oL15!*GI z>aNSzUf4Cncbs*=`W#(y;SBqGR@I*Im(`m+eWeX|4ldk#*CgNZVm%NkcpNP;9cUam zGhV*q#VQhDQo|XodYtb#YlH8&JOpF!{s7??4_$qRJpc?NVT;m9_m-4>bJ~x0$ukdY~?Yso{*48qR1An&k@(M7~<4 ze_UgkQ!#G!xZ24A2fYL^f-?#hr#nA+GqR!-|n66Xlrl!qE+U<*8Z#=-(AMxejb@C z#GJXhNUa?QBV)!PYN9+SgnYZ_(e=+lO*@Y=gtq74eXBERx9=ZayS-zhX%-%dMZ9(l zx61>%$XtmG&p7h7`~99vaei-OFRz`=nsyd`XlpCIZwVyr)`oZOG@N#JZ)EO8uE?Ak zipbGPK|^Lr$6$AK1^GjnC1U%Bg*hiCS(&(X5a?ZC*K>dZbzi_Gtxi_Dc6xr~Fm zY}b{DyU3hBd2BasDK3-c!Kt(|%6oVB?Y<#+w5@0UMXStRxXJ^dT)srU>q>Y|W$u!b zaVSO@9^#XFie0+`Xqf)<=5ZD!hs9?pj>zW#^J$4n{l`@ zg@4wtcp>%A*)g6ntgwYE>S^aG*eCE~K~PD2B5lD|6U3

    Q4!)=GV4}@j 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 _SJo;#ToG3uDxF5=XgSZhrz3MGRQ5SI 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 literal 0 HcmV?d00001 diff --git a/runtime/ops/mapper/unstructuredio/test_cases/example_input/bert_pretraining.pdf b/runtime/ops/mapper/unstructuredio/test_cases/example_input/bert_pretraining.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2394716bcb9d947a5e636d5a7765bb2c1c4f7710 GIT binary patch literal 775166 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 z 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 D9a=VT literal 0 HcmV?d00001 From 8c258abd4e6b4cbd2bc7190f0a7a2b5fc26ae9ed Mon Sep 17 00:00:00 2001 From: qianqiuer <3418979384@qq.com> Date: Tue, 2 Jun 2026 20:43:22 +0800 Subject: [PATCH 2/5] Add Huizhi operator adaptations --- .../data_synthesis_service/README.md | 27 +- .../requirements-npu.txt | 2 + .../data_synthesis_service/requirements.txt | 4 + .../unstructuredio/NPU_ENV_CHECK_REPORT.md | 68 + runtime/ops/mapper/unstructuredio/README.md | 102 +- .../unstructuredio/operator_src/README.md | 61 +- .../unstructuredio/operator_src/__init__.py | 14 +- .../operator_src/adapters/__init__.py | 0 .../operator_src/adapters/npu_adapter.py | 1094 +++++++++++++++++ .../operator_src/adapters/ocr_npu_adapter.py | 815 ++++++++++++ .../adapters/requirements_npu_v1.2_stable.txt | 25 + .../operator_src/check_npu_runtime.py | 129 ++ .../unstructuredio/operator_src/metadata.yml | 24 +- .../unstructuredio/operator_src/process.py | 639 +++++++++- .../operator_src/run_strict_pdf_docx_smoke.py | 78 ++ .../tests/test_check_npu_runtime.py | 65 + .../tests/test_npu_adapter_cpu_fallback.py | 31 + .../operator_src/tests/test_ocr_cpu_patch.py | 45 + .../tests/test_pdf_npu_ocr_priority.py | 390 ++++++ .../tests/test_process_ascend_env.py | 27 + .../tests/test_require_npu_models.py | 229 ++++ .../tests/test_table_transformer_npu.py | 162 +++ 22 files changed, 3934 insertions(+), 97 deletions(-) create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements-npu.txt create mode 100644 runtime/ops/mapper/unstructuredio/NPU_ENV_CHECK_REPORT.md create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/adapters/__init__.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/adapters/npu_adapter.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/adapters/ocr_npu_adapter.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/adapters/requirements_npu_v1.2_stable.txt create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/check_npu_runtime.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/run_strict_pdf_docx_smoke.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_check_npu_runtime.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_npu_adapter_cpu_fallback.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_ocr_cpu_patch.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_pdf_npu_ocr_priority.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_process_ascend_env.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_require_npu_models.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_table_transformer_npu.py diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/README.md b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/README.md index 0351dd3d..5a6e68be 100644 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/README.md +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/README.md @@ -1,12 +1,12 @@ -# data\_synthesis\_service 服务补丁 +# data_synthesis_service 服务补丁 本目录归档独立 HTTP 服务中与数据质量评估相关的代码。 ## 接口 -- `GET /health` -- `POST /synthesize-file` -- `POST /evaluate-file` +- `GET /health` +- `POST /synthesize-file` +- `POST /evaluate-file` ## 本地启动示例 @@ -16,11 +16,12 @@ python -m uvicorn data_synthesis_service.app:app --host 0.0.0.0 --port 18080 ## 依赖 -- `requirements.txt` 是独立服务生产依赖。 -- 基础镜像为 `quay.io/ascend/vllm-ascend:v0.18.0rc1`,对应 Python `3.11.14`、CANN `8.5.1`。 -- 关键版本包括 `vllm==0.18.0+empty`、`vllm_ascend==0.18.0rc1`、`torch==2.9.0+cpu`、`torch_npu==2.9.0.post1+gitee7ba04`。 -- `requirements-base.txt` 只用于无模型接口冒烟测试。 -- DataMate 算子本体依赖在 `operator_src/requirements.txt`。 +- `requirements.txt` 是独立服务生产依赖,完全对标 910b-jss 已验证镜像 `huizhi:test-v018`。 +- 基础镜像固定为 `quay.io/ascend/vllm-ascend:v0.18.0rc1`,对应 Python `3.11.14`、CANN `8.5.1`。 +- 关键版本包括 `vllm==0.18.0+empty`、`vllm_ascend==0.18.0rc1`、`torch==2.9.0+cpu`、`torch_npu==2.9.0.post1+gitee7ba04`。 +- `requirements-base.txt` 只用于无模型接口冒烟测试。 +- `requirements-npu.txt` 是兼容旧文档的别名,等价引用 `requirements.txt`。 +- DataMate 算子本体依赖在 `operator_src/requirements.txt`,不应安装 vLLM。 正式 NPU 构建示例: @@ -29,7 +30,7 @@ docker build -t data-synthesis-service:latest \ -f data_synthesis_service/Dockerfile . ``` -不传构建参数时默认使用基础镜像并安装 `requirements.txt`。无模型接口冒烟测试可显式增加 `--build-arg REQUIREMENTS_FILE=requirements-base.txt`。 +不传构建参数时默认使用 910b-jss 对标基础镜像并安装 `requirements.txt`。无模型接口冒烟测试可显式增加 `--build-arg REQUIREMENTS_FILE=requirements-base.txt`。 Dockerfile 使用 `pip install --no-deps`。这是为了保留 `quay.io/ascend/vllm-ascend:v0.18.0rc1` 中已经验证的 vLLM-Ascend 依赖闭包,避免 pip 重新解析传递依赖导致版本漂移。 @@ -37,7 +38,7 @@ Dockerfile 使用 `pip install --no-deps`。这是为了保留 `quay.io/ascend/v 启动服务前通过环境变量指定容器内模型路径: -- `DATA_SYNTHESIS_MODEL_PATH` -- `DATA_EVALUATOR_MODEL_PATH` +- `DATA_SYNTHESIS_MODEL_PATH` +- `DATA_EVALUATOR_MODEL_PATH` -默认模型挂载点为容器内 `/model`。 \ No newline at end of file +默认模型挂载点为容器内 `/model`。 diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements-npu.txt b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements-npu.txt new file mode 100644 index 00000000..626e52fe --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements-npu.txt @@ -0,0 +1,2 @@ +# Backward-compatible alias for the full NPU/vLLM service dependencies. +-r requirements.txt diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements.txt b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements.txt index d857a7bc..b65dd8c1 100644 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements.txt +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements.txt @@ -1,3 +1,7 @@ +# Independent service production dependencies aligned with 910b-jss huizhi:test-v018. +# Base image: quay.io/ascend/vllm-ascend:v0.18.0rc1 +# Python: 3.11.14, CANN: 8.5.1 +# Do not put these into the DataMate operator_src/requirements.txt. fastapi==0.123.10 uvicorn==0.42.0 pydantic==2.12.5 diff --git a/runtime/ops/mapper/unstructuredio/NPU_ENV_CHECK_REPORT.md b/runtime/ops/mapper/unstructuredio/NPU_ENV_CHECK_REPORT.md new file mode 100644 index 00000000..ad8b0236 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/NPU_ENV_CHECK_REPORT.md @@ -0,0 +1,68 @@ +# unstructuredio NPU 环境自检报告 + +## 自检环境 + +- 服务器:910b-jss +- 测试容器:huizhi +- 测试目录:/home/o_pengjunjie/huizhi +- NPU 选择:ASCEND_RT_VISIBLE_DEVICES=6 + +## 已验证通过 + +- Torch-NPU 可用:`torch_npu==2.7.1` 可正常 import。 +- Torch NPU 设备可用:`torch.npu.is_available()` 返回 True。 +- YOLOX PT 版面模型文件存在:`/home/o_pengjunjie/huizhi/unstructuredio_models/yolox_l.pt`。 +- YOLOX 源码目录存在:`/home/o_pengjunjie/huizhi/unstructuredio_models/YOLOX-main`。 +- PaddleOCR 本地模型目录存在:det、rec、cls 三类模型均已放置。 +- `check_npu_runtime.py` 已采用子进程隔离检查 Torch-NPU 与 Paddle-NPU,并注入 Ascend/NNAL 动态库路径,避免同进程冲突和库路径误判。`process.py` 主进程和 `ocr_npu_adapter.py` worker 也已统一注入 Ascend/NNAL 动态库路径。 + +## 当前未通过项 + +### PaddleOCR-NPU + +当前 `huizhi` 容器中版本如下: + +- `paddlepaddle==3.3.1` +- `paddle-custom-npu==3.3.0` +- `paddleocr==2.7.3` +- CANN/driver:CANN 8.5.1,driver 25.5.2 + +现象:加载 `paddle-custom-npu` 时进入 `aclInit/rtGetDevMsg` 初始化失败: + +```text +Call aclInit(nullptr) failed : 500000 at file /paddle/backends/npu/runtime/runtime.cc line 403 +``` + +已确认 `check_npu_runtime.py` 会注入 Ascend/NNAL 动态库路径,因此该问题不是模型路径缺失,也不是 `libmki.so` / `LD_LIBRARY_PATH` 缺失,而是当前 Paddle custom NPU 组件与容器/驱动组合的兼容问题。 + +补充验证:已在独立临时容器 `huizhi-paddle30-venv` 中创建隔离 venv,并按 Paddle 官方 NPU 推荐组合安装: + +- `paddlepaddle==3.0.0` +- `paddle-custom-npu==3.0.0` +- `paddleocr==2.7.3` + +该组合仍在 `rtGetDevMsg/aclInit` 阶段失败,错误同样为: + +```text +chipType=0 does not support get device msg feature +Call aclInit(nullptr) failed : 500000 at file /paddle/backends/npu/runtime/runtime.cc line 403 +``` + +因此当前阻塞点不是算子代码、OCR 模型路径、动态库路径,也不是单纯的 Paddle 3.3/3.0 版本选择,而是 910b-jss 当前主机驱动/CANN/设备信息接口与 Paddle custom NPU runtime 不兼容。 + +### DOCX 严格模式 + +当前 `huizhi` 容器没有 `soffice` / LibreOffice。DOCX/DOC 严格模式需要先转 PDF 再复用 PDF NPU 链路,因此缺少 `soffice` 时会直接失败,不会静默回退 CPU fast path。 + +## 算子行为 + +- 普通模式:优先尝试 NPU 链路;NPU/OCR 不可用时回退 `fast/auto`,并在 `mode` 中标识 fallback。 +- 严格模式:设置 `requireNpuModels=true` 或 `UNSTRUCTUREDIO_REQUIRE_NPU_MODELS=1` 后,任何 NPU 组件不可用都会直接失败;DOCX/DOC 严格模式只接受完整 `pdf-npu-ocr-hi_res` 视觉链路,不接受只有版面 NPU、OCR 未走 NPU 的结果。 +- 当前交付不会把 PaddleOCR-NPU 误报为成功。 + +## 建议验收环境要求 + +- 使用与 Paddle 官方 NPU wheel 匹配的 CANN/driver/container 组合,或直接使用 Paddle 官方 NPU 标准镜像。 +- 预置 `paddlepaddle`、`paddle-custom-npu`、`paddleocr`,并通过 `python check_npu_runtime.py` 验证 `paddle` 与 `paddleocr` 均可 import。 +- DOCX/DOC 严格验收需安装 `LibreOffice/soffice`。 +- 模型路径按 README 说明挂载到 `/models/unstructuredio/...` 或用环境变量覆盖。 diff --git a/runtime/ops/mapper/unstructuredio/README.md b/runtime/ops/mapper/unstructuredio/README.md index 580daf46..c5e64583 100644 --- a/runtime/ops/mapper/unstructuredio/README.md +++ b/runtime/ops/mapper/unstructuredio/README.md @@ -1,46 +1,94 @@ -# unstructuredio 算子 +# unstructuredio 算子 ## 目录内容 -- `operator_src/` DataMate 算子源码。 -- `test_cases/` 公开 PDF 和 DOCX 测试样本及测试说明。 -- `README.md` 本说明文件。 +- `operator_src/`:DataMate 算子源码目录,压缩该目录内指定文件即可上传平台。 +- `adapter_src/`:NPU/OCR 适配源码与实验归档。 +- `test_cases/`:公开 PDF、DOCX 测试样本和测试说明。 + +## 已实现功能 + +- PDF 优先尝试 `hi_res + yolox + OCR force` 链路。 +- 版面检测模型使用 YOLOX PT 权重,并通过 `torch_npu` 加载到 NPU。 +- 表格结构识别模型使用本地 `microsoft/table-transformer-structure-recognition` 权重,优先通过 `TableTransformerConfig + state_dict` 手工加载到 NPU,避免运行时访问远程模型或额外拉取 ResNet 骨干权重。 +- OCR 适配器优先在独立子进程中加载 PaddleOCR NPU,避免 Paddle NPU 与 Torch-NPU 在同一 Python 进程内冲突;主进程、OCR worker、自检脚本均会注入 Ascend/NNAL 动态库路径。 +- 普通模式下,如果 NPU/OCR 初始化失败,算子会回退到 `fast/auto`,保证工程可用,并在输出 `mode` 中标明 fallback。 +- 严格验收模式下,开启 `requireNpuModels=true` 或 `UNSTRUCTUREDIO_REQUIRE_NPU_MODELS=1` 后,PDF 必须使用完整 `pdf-npu-ocr-hi_res` 链路;OCR native/Tesseract fallback 被禁用,任何 NPU 组件不可用都会直接失败。 +- DOCX/DOC 严格模式先使用 `LibreOffice/soffice` 转 PDF,再复用 PDF NPU 视觉解析链路;只接受完整 `pdf-npu-ocr-hi_res`,缺少 `soffice` 或 OCR-NPU 不可用时直接失败,不静默走 CPU fast path。 +- 输出保持 unstructured 风格 JSON,核心字段包括 `index`、`category`、`text`、`page_number`、`coordinates`、`text_as_html`。 ## 开源模型链接 -- 版面检测模型 `unstructuredio/yolo_x_layout`: [https://huggingface.co/unstructuredio/yolo\_x\_layout](https://huggingface.co/unstructuredio/yolo_x_layout "https://huggingface.co/unstructuredio/yolo_x_layout") -- 表格结构识别模型 `microsoft/table-transformer-structure-recognition`: [https://huggingface.co/microsoft/table-transformer-structure-recognition](https://huggingface.co/microsoft/table-transformer-structure-recognition "https://huggingface.co/microsoft/table-transformer-structure-recognition") -- `YOLOX` 上游开源项目: [https://github.com/Megvii-BaseDetection/YOLOX](https://github.com/Megvii-BaseDetection/YOLOX "https://github.com/Megvii-BaseDetection/YOLOX") +- 版面检测模型 `unstructuredio/yolo_x_layout`: +- 表格结构识别模型 `microsoft/table-transformer-structure-recognition`: +- YOLOX 上游项目: +- PaddleOCR: +- PP-OCRv4 模型说明: + +## 模型路径 + +默认使用容器内 `/models` 挂载点,可通过环境变量覆盖: + +- `UNSTRUCTUREDIO_YOLOX_MODEL_PATH=/models/unstructuredio/yolox_l.pt` +- `UNSTRUCTUREDIO_YOLOX_SRC_PATH=/models/unstructuredio/YOLOX-main` +- `UNSTRUCTUREDIO_OCR_MODEL_ROOT=/models/unstructuredio/paddleocr` +- `UNSTRUCTUREDIO_OCR_DET_MODEL_DIR=/models/unstructuredio/paddleocr/ch_PP-OCRv4_det_infer` +- `UNSTRUCTUREDIO_OCR_REC_MODEL_DIR=/models/unstructuredio/paddleocr/ch_PP-OCRv4_rec_infer` +- `UNSTRUCTUREDIO_OCR_CLS_MODEL_DIR=/models/unstructuredio/paddleocr/ch_ppocr_mobile_v2.0_cls_infer` +- `UNSTRUCTUREDIO_TABLE_MODEL_PATH=/models/unstructuredio/table-transformer-structure-recognition` + +表格结构模型不存在时,算子会关闭 `infer_table_structure`,避免运行时访问远程模型;PDF 表格标题仍会做轻量补强和合并。 -## 路径和模型配置 +## NPU 运行依赖 -算子代码默认使用容器内模型路径: +严格 NPU 模式要求运行环境预置: -- `UNSTRUCTUREDIO_LAYOUT_MODEL_PATH=/models/unstructuredio/yolo_x_layout/yolox_l0.05.onnx` -- `UNSTRUCTUREDIO_TABLE_MODEL_PATH=/models/unstructuredio/table-transformer-structure-recognition` +- Ascend CANN/driver,并能看到至少 1 张 NPU。 +- `torch`、`torch-npu`、`torchvision`。 +- `paddlepaddle`、`paddle-custom-npu`、`paddleocr`。 +- `unstructured`、`unstructured-inference`、`pdf2image`、`pypdfium2`、`pikepdf`、`pi_heif`、`opencv-python-headless`。 +- `einops`、`loguru` 和 YOLOX 源码目录。 +- DOCX/DOC 严格模式额外要求 `LibreOffice/soffice`。 -`/models` 是容器内约定挂载点。可把本机任意模型目录挂载到容器内 `/models`,或通过上述环境变量改成其他容器内路径。 +910b-jss 临时 `huizhi` 容器当前已验证 Torch-NPU 可用,`torch.npu.is_available()` 为 True;YOLOX PT 版面模型可走 Torch-NPU;表格结构识别 `microsoft/table-transformer-structure-recognition` 已验证模型参数、输入张量和输出张量均在 `npu:0`,warmup 后单次前向约 0.028 秒。该临时容器中的 `paddlepaddle==3.3.1`、`paddle-custom-npu==3.3.0` 在加载 NPU custom device 时触发 `aclInit/rtGetDevMsg` 初始化失败。已在独立临时容器 `huizhi-paddle30-venv` 中按 Paddle 官方推荐组合验证 `paddlepaddle==3.0.0`、`paddle-custom-npu==3.0.0`、`paddleocr==2.7.3`,仍失败于同一 `rtGetDevMsg/aclInit` 调用。自检脚本已注入 Ascend/NNAL 动态库路径,因此该问题不是模型路径或 `LD_LIBRARY_PATH` 缺失,而是当前主机驱动/CANN/设备信息接口与 Paddle custom NPU runtime 不兼容。代码会在严格模式下直接失败,普通模式下明确 fallback,不会伪装成 OCR NPU 成功。 ## 如何生成 DataMate 上传包 -建议生成的上传包文件名为 `unstructuredio.zip`。 +压缩 `operator_src/` 目录中的以下内容生成 `unstructuredio.zip`: + +- `metadata.yml` +- `process.py` +- `__init__.py` +- `requirements.txt` +- `README.md` +- `adapters/` + +不要把 `tests/`、`test_cases/`、`check_npu_runtime.py`、`run_strict_pdf_docx_smoke.py` 放入 DataMate 算子上传包。 + +## 平台测试流程 + +1. 在 DataMate 算子市场上传 `unstructuredio.zip`。 +2. 新建数据处理任务,选择 `unstructuredio` 算子。 +3. 上传 `test_cases/example_input/` 下的 PDF 或 DOCX 样本。 +4. 普通功能测试使用默认参数;严格 NPU 验收测试设置 `requireNpuModels=true`。 +5. 下载输出 JSON,检查 `elements[].category`、`text`、`page_number`、`coordinates`、`text_as_html` 和顶层 `mode`。 + +## 环境自检 -方式一:如果平台接受压缩包根目录直接包含算子文件,则压缩 `operator_src/` 目录中的全部文件。 +交付源码目录提供 `operator_src/check_npu_runtime.py`,用于检查 Python 依赖、模型路径、NPU 组件和 `soffice`: -方式二:如果平台要求压缩包内有顶层算子目录,则新建临时目录 `unstructuredio/`,将 `operator_src/` 中的以下文件放入该目录后压缩: +```bash +cd operator_src +python check_npu_runtime.py +``` -- `metadata.yml` -- `process.py` -- `__init__.py` -- `requirements.txt` -- `README.md` +该脚本只用于验收环境检查,不放入 DataMate 上传包。脚本采用子进程隔离方式分别检查 Torch-NPU 与 Paddle-NPU,避免两个 NPU 栈在同一 Python 进程内互相污染。 -不要把 `test_cases/` 放入 DataMate 算子上传包。 +完整 NPU 依赖和 `soffice` 就绪后,可运行严格模式 smoke 测试: -## 平台测试 +```bash +cd operator_src +python run_strict_pdf_docx_smoke.py ../test_cases/example_input/attention_is_all_you_need.pdf ../test_cases/example_input/docx_corpus_sample_1.docx +``` -1. 在 DataMate 算子市场上传按上述规则生成的上传包。 -2. 新建数据处理任务,选择 `unstructuredio` 算子。 -3. 上传 `test_cases/example_input/` 下的 PDF 或 DOCX 样本。 -4. 运行任务并下载输出 JSON。 -5. 按 `test_cases/README.md` 中的检查项确认输出结构、页码、坐标和表格字段。 \ No newline at end of file +PDF 期望输出 `mode=pdf-npu-ocr-hi_res`;DOCX 期望输出 `mode=docx-visual-pdf-npu-ocr-hi_res`。 diff --git a/runtime/ops/mapper/unstructuredio/operator_src/README.md b/runtime/ops/mapper/unstructuredio/operator_src/README.md index db0c2f02..a81c372a 100644 --- a/runtime/ops/mapper/unstructuredio/operator_src/README.md +++ b/runtime/ops/mapper/unstructuredio/operator_src/README.md @@ -1,23 +1,60 @@ -# unstructuredio 算子源码 +# unstructuredio 算子源码 -本目录是 DataMate 平台上传包中的算子源码。 +本目录是 DataMate 平台上传包使用的算子源码。 ## 功能 - 读取 DataMate 传入的 `filePath` 文件。 - 支持 PDF、DOCX、DOC 及 `unstructured` 可识别的其他文档格式。 -- 输出 `unstructured` 风格 JSON。 +- 输出 unstructured 风格 JSON。 - 核心字段包括 `index`、`category`、`text`、`page_number`、`coordinates`、`text_as_html`。 -## 默认行为 +## 执行链路 -- PDF 默认使用 `auto` 策略,尽量保持与 `unstructured` 原生输出一致。 -- DOCX 默认启用兼容型快路径,失败时自动回退到 `unstructured` 原生解析。 -- PDF 默认开启首页明显竖排乱码抑制,只过滤明显坏结果。 -- 输出文件默认保存为 JSON。 +- PDF 默认优先尝试 `YOLOX PT NPU + PaddleOCR NPU`,解析参数为 `hi_res + yolox + OCR force`。 +- 版面检测由 `adapters/npu_adapter.py` 适配,使用 Torch-NPU 加载 YOLOX PT 权重。 +- 表格结构识别优先使用本地 `microsoft/table-transformer-structure-recognition` 权重,通过 `TableTransformerConfig + state_dict` 手工加载到 NPU,并将输入张量迁移到同一设备。 +- OCR 由 `adapters/ocr_npu_adapter.py` 适配,优先在独立子进程加载 PaddleOCR NPU,避免与主进程 Torch-NPU 冲突;主进程、OCR worker、自检脚本均会注入 Ascend/NNAL 动态库路径。 +- 普通模式下,NPU/OCR 不可用或输出明显不合格时可回退到 `fast/auto`,保证工程可用。 +- 严格模式下,设置 `requireNpuModels=true` 或 `UNSTRUCTUREDIO_REQUIRE_NPU_MODELS=1` 后,PDF 必须走完整 `pdf-npu-ocr-hi_res` 链路;OCR native/Tesseract fallback 被禁用,失败时直接报错。 +- DOCX/DOC 严格模式先用 `LibreOffice/soffice` 转 PDF,再复用 PDF NPU 链路;运行环境必须提供 `soffice`,且只接受完整 `pdf-npu-ocr-hi_res`,不接受只有版面 NPU、OCR 未走 NPU 的结果。 -## 注册关系 +## 适配源码 -- `metadata.yml` 的 `raw_id` 为 `UnstructuredIOMapper`。 -- `process.py` 中的类名为 `UnstructuredIOMapper`。 -- `__init__.py` 注册路径为 `ops.user.unstructuredio.process`。 +- `adapters/npu_adapter.py`:YOLOX PT 版面模型 NPU 适配、模型加载、Torch-NPU 推理和 `unstructured-inference` 兼容层。 +- `adapters/ocr_npu_adapter.py`:PaddleOCR NPU 独立进程适配,并注入 `pytesseract` / `unstructured_paddleocr` 兼容接口代理。 +- `adapters/requirements_npu_v1.2_stable.txt`:910B NPU 实验环境依赖版本参考。 + +## 模型路径 + +- `UNSTRUCTUREDIO_YOLOX_MODEL_PATH`:默认 `/models/unstructuredio/yolox_l.pt`。 +- `UNSTRUCTUREDIO_YOLOX_SRC_PATH`:默认优先查找算子内 `adapters/YOLOX-main`,也支持 `/models/unstructuredio/YOLOX-main`。 +- `UNSTRUCTUREDIO_OCR_MODEL_ROOT`:默认 `/models/unstructuredio/paddleocr`。 +- `UNSTRUCTUREDIO_OCR_DET_MODEL_DIR`:默认 `/models/unstructuredio/paddleocr/ch_PP-OCRv4_det_infer`。 +- `UNSTRUCTUREDIO_OCR_REC_MODEL_DIR`:默认 `/models/unstructuredio/paddleocr/ch_PP-OCRv4_rec_infer`。 +- `UNSTRUCTUREDIO_OCR_CLS_MODEL_DIR`:默认 `/models/unstructuredio/paddleocr/ch_ppocr_mobile_v2.0_cls_infer`。 +- `UNSTRUCTUREDIO_TABLE_MODEL_PATH`:默认 `/models/unstructuredio/table-transformer-structure-recognition`。 + +表格结构模型不存在时会关闭 `infer_table_structure`,避免访问远程模型。 + +## 验证 + +本地单测: + +```bash +python -m pytest operator_src/tests -q +``` + +验收环境自检: + +```bash +python operator_src/check_npu_runtime.py +``` + +严格模式 PDF/DOCX smoke 测试: + +```bash +python operator_src/run_strict_pdf_docx_smoke.py test_cases/example_input/attention_is_all_you_need.pdf test_cases/example_input/docx_corpus_sample_1.docx +``` + +`check_npu_runtime.py` 和 `run_strict_pdf_docx_smoke.py` 用于交付验收环境检查,不放入 DataMate 上传包。DOCX 严格模式要求系统存在 `soffice`。910b-jss 临时 `huizhi` 容器当前已验证 Torch-NPU/YOLOX PT 可用;表格结构识别模型已验证模型参数、输入张量和输出张量均在 `npu:0`,warmup 后单次前向约 0.028 秒;PaddleOCR-NPU 在该容器 `paddlepaddle==3.3.1/paddle-custom-npu==3.3.0` 下于 `aclInit/rtGetDevMsg` 阶段失败。另在独立临时容器中使用 Paddle 官方推荐 `paddlepaddle==3.0.0/paddle-custom-npu==3.0.0` 组合验证,仍失败于同一 `rtGetDevMsg/aclInit` 调用。自检脚本已注入 Ascend/NNAL 动态库路径,因此不是模型路径或 `LD_LIBRARY_PATH` 缺失。严格模式会直接失败,普通模式会明确 fallback。 diff --git a/runtime/ops/mapper/unstructuredio/operator_src/__init__.py b/runtime/ops/mapper/unstructuredio/operator_src/__init__.py index d43c4e5f..0a7011a5 100644 --- a/runtime/ops/mapper/unstructuredio/operator_src/__init__.py +++ b/runtime/ops/mapper/unstructuredio/operator_src/__init__.py @@ -1,8 +1,12 @@ # -*- coding: utf-8 -*- -from datamate.core.base_op import OPERATORS +try: + from datamate.core.base_op import OPERATORS +except ImportError: + OPERATORS = None -OPERATORS.register_module( - module_name="UnstructuredIOMapper", - module_path="ops.user.unstructuredio.process", -) +if OPERATORS is not None: + OPERATORS.register_module( + module_name="UnstructuredIOMapper", + module_path="ops.user.unstructuredio.process", + ) diff --git a/runtime/ops/mapper/unstructuredio/operator_src/adapters/__init__.py b/runtime/ops/mapper/unstructuredio/operator_src/adapters/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/runtime/ops/mapper/unstructuredio/operator_src/adapters/npu_adapter.py b/runtime/ops/mapper/unstructuredio/operator_src/adapters/npu_adapter.py new file mode 100644 index 00000000..cc48fd03 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/adapters/npu_adapter.py @@ -0,0 +1,1094 @@ +import os +import sys +import types +import inspect +import torch +import torch_npu +import numpy as np +import requests +from torchvision.ops import nms +from requests.exceptions import ConnectionError +from urllib.parse import urlparse, urlunparse + +# 如用户未显式设置,默认使用 hf-mirror +os.environ.setdefault("HF_ENDPOINT", "https://hf-mirror.com") + +# ========================================== +# 0. 强力断网拦截 & 基础补丁 +# ========================================== +_orig_request = requests.Session.request + +def mocked_request(self, method, url, *args, **kwargs): + # 仅阻断 YOLOX 相关远程拉取,避免影响表格结构模型(table-transformer)下载 + lowered_url = str(url).lower() + if "yolox" in lowered_url or "yolo_x_layout" in lowered_url: + resp = requests.Response() + resp.status_code = 404 + return resp + + # 强制将 huggingface.co 请求路由到 HF_ENDPOINT(例如 https://hf-mirror.com) + hf_endpoint = os.environ.get("HF_ENDPOINT", "").strip() + if hf_endpoint and "huggingface.co" in lowered_url: + try: + src = urlparse(str(url)) + dst = urlparse(hf_endpoint) + if dst.scheme and dst.netloc: + url = urlunparse((dst.scheme, dst.netloc, src.path, src.params, src.query, src.fragment)) + except Exception: + pass + + return _orig_request(self, method, url, *args, **kwargs) + +requests.Session.request = mocked_request + +# ========================================== +# 1. 定义增强版 LayoutElements +# ========================================== +class NpuLayoutElements(list): + def __init__(self, items=None, **kwargs): + self._element_coords = kwargs.pop("element_coords", None) + self._texts = kwargs.pop("texts", None) + self._sources = kwargs.pop("sources", None) + self._element_class_ids = kwargs.pop("element_class_ids", None) + self._element_class_id_map = kwargs.pop("element_class_id_map", None) + self._probs = kwargs.pop("probs", kwargs.pop("element_probs", None)) + self._is_extracted_array = kwargs.pop("is_extracted_array", None) + self.text_as_html = kwargs.pop("text_as_html", None) + self.table_as_cells = kwargs.pop("table_as_cells", None) + if self._element_coords is not None: + self._element_coords = np.asarray(self._element_coords, dtype=float) + if self._texts is not None: + self._texts = np.asarray(self._texts, dtype=object) + if self._sources is not None: + self._sources = np.asarray(self._sources, dtype=object) + if self._element_class_ids is not None: + self._element_class_ids = np.asarray(self._element_class_ids, dtype=np.int64) + if self._probs is not None: + self._probs = np.asarray(self._probs, dtype=object) + if self._is_extracted_array is not None: + self._is_extracted_array = np.asarray(self._is_extracted_array, dtype=bool) + if self.text_as_html is not None: + self.text_as_html = np.asarray(self.text_as_html, dtype=object) + if self.table_as_cells is not None: + self.table_as_cells = np.asarray(self.table_as_cells, dtype=object) + if self._element_class_id_map is None: + self._element_class_id_map = self._default_class_id_map() + if items is None and self._element_coords is not None: + items = self._build_items_from_arrays() + super().__init__(items if items is not None else []) + self._sync_arrays_from_items_if_needed() + for k, v in kwargs.items(): + setattr(self, k, v) + + def _default_class_id_map(self): + try: + from unstructured.documents.elements import ElementType + return { + 0: ElementType.UNCATEGORIZED_TEXT, + 1: ElementType.IMAGE, + 2: ElementType.TABLE, + 3: ElementType.FORMULA, + } + except Exception: + return { + 0: "UncategorizedText", + 1: "Image", + 2: "Table", + 3: "Formula", + } + + def _id_to_type(self, class_id): + return self.element_class_id_map.get(int(class_id), "Text") + + def _build_items_from_arrays(self): + from unstructured_inference.inference.layoutelement import LayoutElement + coords = np.asarray(self._element_coords if self._element_coords is not None else np.empty((0, 4))) + texts = np.asarray(self._texts if self._texts is not None else [None] * len(coords), dtype=object) + sources = np.asarray(self._sources if self._sources is not None else [None] * len(coords), dtype=object) + class_ids = np.asarray( + self._element_class_ids if self._element_class_ids is not None else np.zeros(len(coords)), + dtype=np.int64, + ) + probs = np.asarray(self._probs if self._probs is not None else [0.0] * len(coords), dtype=object) + items = [] + for idx, box in enumerate(coords): + text = texts[idx] if idx < len(texts) else None + source = sources[idx] if idx < len(sources) else None + prob = probs[idx] if idx < len(probs) else 0.0 + element_type = self._id_to_type(class_ids[idx] if idx < len(class_ids) else 0) + items.append( + LayoutElement.from_coords( + *box, + text="" if text is None else text, + source=source, + type=element_type, + prob=None if prob is None else float(prob), + ) + ) + return items + + def _type_to_id(self, element_type): + reverse = {v: k for k, v in self.element_class_id_map.items()} + if element_type in reverse: + return int(reverse[element_type]) + alias_map = { + "Text": 0, + "NarrativeText": 0, + "Title": 0, + "Caption": 0, + "List-item": 0, + "ListItem": 0, + "Image": 1, + "Picture": 1, + "Table": 2, + "Formula": 3, + } + return alias_map.get(str(element_type or "Text"), 0) + + def _sync_arrays_from_items_if_needed(self): + for element in self: + if getattr(element, "text", None) is None: + try: + element.text = "" + except AttributeError: + pass + if self._element_class_id_map is None: + self._element_class_id_map = self._default_class_id_map() + if self._element_coords is None: + self._element_coords = self._coords_from_items() + if self._texts is None: + self._texts = np.array([getattr(x, "text", "") for x in self], dtype=object) + if self._sources is None: + self._sources = np.array([getattr(x, "source", None) for x in self], dtype=object) + if self._element_class_ids is None: + self._element_class_ids = np.array( + [self._type_to_id(getattr(x, "type", "Text")) for x in self], + dtype=np.int64, + ) + if self._probs is None: + self._probs = np.array([getattr(x, "prob", 0.0) for x in self], dtype=object) + if self._is_extracted_array is None: + self._is_extracted_array = np.array( + [bool(getattr(x, "is_extracted", False)) for x in self], + dtype=bool, + ) + if self.text_as_html is None: + self.text_as_html = np.array([getattr(x, "text_as_html", None) for x in self], dtype=object) + if self.table_as_cells is None: + self.table_as_cells = np.array([getattr(x, "table_as_cells", None) for x in self], dtype=object) + + def _coords_from_items(self): + coords = [] + for el in self: + if hasattr(el, 'bbox'): + bbox = el.bbox + if hasattr(bbox, 'x1'): + coords.append([bbox.x1, bbox.y1, bbox.x2, bbox.y2]) + elif isinstance(bbox, (list, tuple, np.ndarray)) and len(bbox) >= 4: + coords.append([bbox[0], bbox[1], bbox[2], bbox[3]]) + else: + coords.append([0, 0, 0, 0]) + elif hasattr(el, 'x1') and hasattr(el, 'y1'): + coords.append([el.x1, el.y1, el.x2, el.y2]) + else: + coords.append([0, 0, 0, 0]) + return np.array(coords, dtype=float) if coords else np.empty((0, 4), dtype=float) + + @property + def element_class_ids(self): + return self._element_class_ids + + @property + def element_class_id_map(self): + return self._element_class_id_map + + @property + def element_coords(self): + return self._element_coords + + @property + def x1(self): return self.element_coords[:, 0] + @property + def y1(self): return self.element_coords[:, 1] + @property + def x2(self): return self.element_coords[:, 2] + @property + def y2(self): return self.element_coords[:, 3] + @property + def widths(self): return np.maximum(self.x2 - self.x1, 0) + @property + def heights(self): return np.maximum(self.y2 - self.y1, 0) + @property + def areas(self): return self.widths * self.heights + @property + def element_probs(self): return self._probs + @element_probs.setter + def element_probs(self, values): + self._probs = np.asarray(values, dtype=object) + @property + def is_extracted_array(self): return self._is_extracted_array + @is_extracted_array.setter + def is_extracted_array(self, values): + self._is_extracted_array = np.asarray(values, dtype=bool) + + @property + def texts(self): + return self._texts + + @texts.setter + def texts(self, values): + self._texts = np.asarray(values, dtype=object) + for i, val in enumerate(values): + if i < len(self): + if hasattr(self[i], 'text'): + self[i].text = val + else: + try: + setattr(self[i], 'text', val) + except AttributeError: + pass + + @property + def probs(self): + return self._probs + + @property + def sources(self): + return self._sources + + def slice(self, selection): + if isinstance(selection, np.ndarray) and selection.dtype == bool: + indices = np.where(selection)[0] + elif isinstance(selection, (list, np.ndarray)): + indices = np.asarray(selection) + elif isinstance(selection, slice): + indices = np.arange(len(self))[selection] + else: + indices = np.asarray([selection]) + subset = [self[int(i)] for i in indices] + return NpuLayoutElements( + subset, + element_coords=self.element_coords[indices], + texts=self.texts[indices], + sources=self.sources[indices], + element_class_ids=self.element_class_ids[indices], + element_class_id_map=self.element_class_id_map, + probs=self.probs[indices], + is_extracted_array=self.is_extracted_array[indices], + text_as_html=self.text_as_html[indices], + table_as_cells=self.table_as_cells[indices], + ) + + def iter_elements(self): + return iter(self) + + def as_list(self): + return list(self) + + @classmethod + def concatenate(cls, layouts): + combined_items = [] + coords = [] + texts = [] + sources = [] + class_ids = [] + probs = [] + text_as_html = [] + table_as_cells = [] + is_extracted_array = [] + class_id_map = None + for layout in layouts: + combined_items.extend(layout) + if hasattr(layout, "element_coords"): + coords.append(layout.element_coords) + texts.append(layout.texts) + sources.append(layout.sources) + class_ids.append(layout.element_class_ids) + probs.append(layout.probs) + text_as_html.append(layout.text_as_html) + table_as_cells.append(layout.table_as_cells) + is_extracted_array.append(layout.is_extracted_array) + class_id_map = getattr(layout, "element_class_id_map", class_id_map) + if coords: + return cls( + items=combined_items, + element_coords=np.concatenate(coords) if coords else np.empty((0, 4)), + texts=np.concatenate(texts) if texts else np.array([], dtype=object), + sources=np.concatenate(sources) if sources else np.array([], dtype=object), + element_class_ids=np.concatenate(class_ids) if class_ids else np.array([], dtype=np.int64), + element_class_id_map=class_id_map, + probs=np.concatenate(probs) if probs else np.array([], dtype=object), + is_extracted_array=np.concatenate(is_extracted_array) if is_extracted_array else np.array([], dtype=bool), + text_as_html=np.concatenate(text_as_html) if text_as_html else np.array([], dtype=object), + table_as_cells=np.concatenate(table_as_cells) if table_as_cells else np.array([], dtype=object), + ) + return cls(items=combined_items) + + +def _as_npu_layout_elements(elements): + if isinstance(elements, NpuLayoutElements): + converted = elements + elif elements is None: + converted = NpuLayoutElements([]) + else: + converted = NpuLayoutElements(list(elements)) + for element in converted: + if getattr(element, "text", None) is None: + try: + element.text = "" + except AttributeError: + pass + return converted + + +def _sync_page_layout_arrays(page): + page.elements = _as_npu_layout_elements(getattr(page, "elements", [])) + page.elements_array = page.elements + return page + + +class NpuTextRegions(NpuLayoutElements): + @classmethod + def from_list(cls, regions): + return cls(items=list(regions)) + + +def _apply_textregions_compat_patch(): + try: + import unstructured_inference.inference.elements as elements_pkg + elements_pkg.TextRegions = NpuTextRegions + except Exception: + pass + try: + import unstructured_inference.inference.layoutelement as layoutelement_pkg + layoutelement_pkg.LayoutElements = NpuLayoutElements + original_partition_groups = layoutelement_pkg.partition_groups_from_regions + + def _partition_groups_from_regions_compat(regions): + groups = original_partition_groups(regions) + return [NpuTextRegions.from_list(group) for group in groups] + + layoutelement_pkg.partition_groups_from_regions = _partition_groups_from_regions_compat + except Exception: + pass + +# ========================================== +# 2. 核心适配器入口 +# ========================================== +class NpuInferenceContext: + def __enter__(self): + return self + def __exit__(self, exc_type, exc_val, exc_tb): + pass + +# ========================================== +# 3. NPU 强力安全算子 (带同步检测) +# ========================================== + +def safe_add(a, b): + try: + res = a + b + torch.npu.synchronize() + return res + except Exception: + return (a.cpu() + b.cpu()).to(a.device) + +def safe_cat(tensors, dim=1): + try: + res = torch.cat(tensors, dim=dim) + torch.npu.synchronize() + return res + except Exception: + cpu_tensors = [t.cpu() for t in tensors] + if not cpu_tensors: return torch.tensor([], device=tensors[0].device) + return torch.cat(cpu_tensors, dim=dim).to(tensors[0].device) + +def safe_sigmoid(x): + try: + res = torch.sigmoid(x) + torch.npu.synchronize() + return res + except Exception: + return torch.sigmoid(x.cpu()).to(x.device) + +def safe_exp(x): + try: + res = torch.exp(x) + torch.npu.synchronize() + return res + except Exception: + return torch.exp(x.cpu()).to(x.device) + +class SafeNpuSiLU(torch.nn.Module): + def __init__(self, inplace=False): + super().__init__() + + def forward(self, x): + try: + x = x.contiguous() + res = x * torch.sigmoid(x) + torch.npu.synchronize() + return res + except Exception: + device = x.device + x_cpu = x.cpu() + return (x_cpu * torch.sigmoid(x_cpu)).to(device) + +class SafeNpuUpsample(torch.nn.Module): + def __init__(self, size=None, scale_factor=None, mode='nearest', align_corners=None): + super().__init__() + self.size = size + self.scale_factor = scale_factor + self.mode = mode + self.align_corners = align_corners + self.op = torch.nn.Upsample(size, scale_factor, mode, align_corners) + + def forward(self, x): + dev = x.device + return self.op(x.cpu()).to(dev) + +class SafeNpuMaxPool2d(torch.nn.Module): + def __init__(self, kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False): + super().__init__() + self.op = torch.nn.MaxPool2d(kernel_size, stride, padding, dilation, return_indices, ceil_mode) + + def forward(self, x): + dev = x.device + return self.op(x.cpu()).to(dev) + +# ========================================== +# 4. YOLOX 模块补丁 +# ========================================== + +def npu_focus_forward(self, x): + target_device = x.device + x_cpu = x.cpu().float() + patch_top_left = x_cpu[..., ::2, ::2] + patch_bot_left = x_cpu[..., 1::2, ::2] + patch_top_right = x_cpu[..., ::2, 1::2] + patch_bot_right = x_cpu[..., 1::2, 1::2] + x_cat = torch.cat( + (patch_top_left, patch_bot_left, patch_top_right, patch_bot_right), + dim=1, + ).contiguous() + + x_npu = x_cat.to(target_device) + conv_out_npu = self.conv.conv(x_npu) + res_cpu = conv_out_npu.cpu() + res_cpu = res_cpu * torch.sigmoid(res_cpu) + return res_cpu.to(target_device) + +def npu_bottleneck_forward(self, x): + y = self.conv2(self.conv1(x)) + if self.use_add: + y = safe_add(y, x) + return y + +def npu_csplayer_forward(self, x): + x_1 = self.conv1(x) + x_2 = self.conv2(x) + x_1 = self.m(x_1) + x = safe_cat((x_1, x_2), dim=1) + return self.conv3(x) + +def npu_spp_forward(self, x): + x = self.conv1(x) + x_1 = self.m[0](x) + x_2 = self.m[1](x) + x_3 = self.m[2](x) + x = safe_cat((x, x_1, x_2, x_3), dim=1) + return self.conv2(x) + +def npu_yolopafpn_forward(self, input): + out_features = self.backbone(input) + features = [out_features[f] for f in self.in_features] + [x2, x1, x0] = features + + fpn_out0 = self.lateral_conv0(x0) + f_out0 = self.upsample(fpn_out0) + f_out0 = safe_cat([f_out0, x1], 1) + f_out0 = self.C3_p4(f_out0) + + fpn_out1 = self.reduce_conv1(f_out0) + f_out1 = self.upsample(fpn_out1) + f_out1 = safe_cat([f_out1, x2], 1) + pan_out2 = self.C3_p3(f_out1) + + p_out1 = self.bu_conv2(pan_out2) + p_out1 = safe_cat([p_out1, fpn_out1], 1) + pan_out1 = self.C3_n3(p_out1) + + p_out0 = self.bu_conv1(pan_out1) + p_out0 = safe_cat([p_out0, fpn_out0], 1) + pan_out0 = self.C3_n4(p_out0) + + return (pan_out2, pan_out1, pan_out0) + +def npu_yolohead_forward(self, xin, labels=None, imgs=None): + outputs = [] + for k, (cls_conv, reg_conv, stride_this_level, x) in enumerate( + zip(self.cls_convs, self.reg_convs, self.strides, xin) + ): + x = self.stems[k](x) + cls_x = x + reg_x = x + + cls_feat = cls_conv(cls_x) + cls_output = self.cls_preds[k](cls_feat) + + reg_feat = reg_conv(reg_x) + reg_output = self.reg_preds[k](reg_feat) + obj_output = self.obj_preds[k](reg_feat) + + if self.training: + output = torch.cat( + [reg_output, obj_output.sigmoid(), cls_output.sigmoid()], 1 + ) + else: + sig_obj = safe_sigmoid(obj_output) + sig_cls = safe_sigmoid(cls_output) + output = safe_cat([reg_output, sig_obj, sig_cls], 1) + + outputs.append(output) + + if self.training: + return outputs + else: + self.hw = [x.shape[-2:] for x in outputs] + outputs_flattened = [x.flatten(start_dim=2) for x in outputs] + cat_out = safe_cat(outputs_flattened, dim=2) + try: + outputs = cat_out.permute(0, 2, 1).contiguous() + torch.npu.synchronize() + except Exception: + outputs = cat_out.cpu().permute(0, 2, 1).contiguous() + + if self.decode_in_inference: + return self.decode_outputs(outputs, dtype=xin[0].type()) + else: + return outputs + +def npu_yolohead_decode_outputs(self, outputs, dtype=None): + outputs = outputs.cpu() + grids = [] + strides = [] + + for (hsize, wsize), stride in zip(self.hw, self.strides): + yv, xv = torch.meshgrid([torch.arange(hsize), torch.arange(wsize)]) + grid = torch.stack((xv, yv), 2).view(1, -1, 2) + grids.append(grid) + shape = grid.shape[:2] + strides.append(torch.full((*shape, 1), stride)) + + grids = torch.cat(grids, dim=1).type(outputs.dtype) + strides = torch.cat(strides, dim=1).type(outputs.dtype) + + outputs_xy = outputs[..., :2] + outputs_wh = outputs[..., 2:4] + outputs_rest = outputs[..., 4:] + + outputs_xy = (outputs_xy + grids) * strides + outputs_wh = torch.exp(outputs_wh) * strides + + return torch.cat([outputs_xy, outputs_wh, outputs_rest], dim=-1) + +# ========================================== +# 5. 模型结构优化 +# ========================================== + +def optimize_model_for_npu(model): + print("[NPU Adapter] Optimizing model structure for Ascend NPU...") + from yolox.models.network_blocks import BaseConv + import torch.nn as nn + + counts = {"bn_fused": 0, "silu_replaced": 0, "upsample_replaced": 0, "maxpool_replaced": 0} + + def recursive_replace(m): + for name, child in m.named_children(): + if isinstance(child, nn.SiLU): + setattr(m, name, SafeNpuSiLU()) + counts["silu_replaced"] += 1 + elif isinstance(child, nn.Upsample): + safe_up = SafeNpuUpsample( + size=child.size, + scale_factor=child.scale_factor, + mode=child.mode, + align_corners=child.align_corners + ) + setattr(m, name, safe_up) + counts["upsample_replaced"] += 1 + elif isinstance(child, nn.MaxPool2d): + safe_pool = SafeNpuMaxPool2d( + kernel_size=child.kernel_size, + stride=child.stride, + padding=child.padding, + dilation=child.dilation, + return_indices=child.return_indices, + ceil_mode=child.ceil_mode + ) + setattr(m, name, safe_pool) + counts["maxpool_replaced"] += 1 + else: + recursive_replace(child) + + recursive_replace(model) + + for name, m in model.named_modules(): + if isinstance(m, BaseConv): + if hasattr(m, "bn") and isinstance(m.bn, nn.BatchNorm2d): + conv = m.conv + bn = m.bn + with torch.no_grad(): + w = conv.weight + if conv.bias is None: + b = torch.zeros(w.shape[0], device=w.device, dtype=w.dtype) + else: + b = conv.bias + bn_mean = bn.running_mean + bn_var = bn.running_var + bn_gamma = bn.weight + bn_beta = bn.bias + bn_eps = bn.eps + inv_std = 1.0 / torch.sqrt(bn_var + bn_eps) + w_fused = w * (bn_gamma * inv_std).reshape(-1, 1, 1, 1) + b_fused = (b - bn_mean) * (bn_gamma * inv_std) + bn_beta + m.conv.weight.copy_(w_fused) + if m.conv.bias is None: + m.conv.bias = torch.nn.Parameter(b_fused) + else: + m.conv.bias.copy_(b_fused) + m.bn = nn.Identity() + counts["bn_fused"] += 1 + + print(f"[NPU Adapter] Optimization Stats: {counts}") + +def apply_patches(): + global _ORIGINAL_GET_MODEL + print("[NPU Adapter] Applying monkey patches...") + _apply_textregions_compat_patch() + import unstructured_inference.models.base as model_base + if _ORIGINAL_GET_MODEL is None and model_base.get_model is not npu_get_model: + _ORIGINAL_GET_MODEL = model_base.get_model + model_base.get_model = npu_get_model + + try: + import unstructured_inference.inference.layout as layout_module + layout_module.get_model = npu_get_model + except ImportError: pass + + from unstructured_inference.inference.layout import PageLayout + # 覆盖 PageLayout 的构造工厂方法 + PageLayout.from_image = classmethod(npu_pagelayout_from_image) + + from unstructured_inference.models.yolox import UnstructuredYoloXModel + UnstructuredYoloXModel.predict = npu_yolox_predict + + import unstructured_inference.inference.layoutelement as layoutelement_pkg + layoutelement_pkg.LayoutElements = NpuLayoutElements + sys.modules['unstructured_inference.inference.layoutelement'].LayoutElements = NpuLayoutElements + + try: + from yolox.models.network_blocks import Focus, Bottleneck, CSPLayer, SPPBottleneck + from yolox.models.yolo_pafpn import YOLOPAFPN + from yolox.models.yolo_head import YOLOXHead + + _ORIGINAL_YOLOX_FORWARDS.setdefault("Focus", Focus.forward) + _ORIGINAL_YOLOX_FORWARDS.setdefault("Bottleneck", Bottleneck.forward) + _ORIGINAL_YOLOX_FORWARDS.setdefault("CSPLayer", CSPLayer.forward) + _ORIGINAL_YOLOX_FORWARDS.setdefault("SPPBottleneck", SPPBottleneck.forward) + _ORIGINAL_YOLOX_FORWARDS.setdefault("YOLOPAFPN", YOLOPAFPN.forward) + _ORIGINAL_YOLOX_FORWARDS.setdefault("YOLOXHead", YOLOXHead.forward) + _ORIGINAL_YOLOX_FORWARDS.setdefault("YOLOXHead.decode_outputs", YOLOXHead.decode_outputs) + + Focus.forward = npu_focus_forward + print("✅ Patch: Focus (Hybrid CPU/NPU).") + Bottleneck.forward = npu_bottleneck_forward + print("✅ Patch: Bottleneck (Safe Add w/ Sync).") + CSPLayer.forward = npu_csplayer_forward + print("✅ Patch: CSPLayer (Safe Cat w/ Sync).") + SPPBottleneck.forward = npu_spp_forward + print("✅ Patch: SPPBottleneck (Safe Cat w/ Sync).") + YOLOPAFPN.forward = npu_yolopafpn_forward + print("✅ Patch: YOLOPAFPN (Re-implemented with Safe Cat).") + YOLOXHead.forward = npu_yolohead_forward + print("✅ Patch: YOLOXHead (Safe Sigmoid & Cat).") + YOLOXHead.decode_outputs = npu_yolohead_decode_outputs + print("✅ Patch: YOLOXHead.decode_outputs (Force CPU).") + + except ImportError as e: + print(f"⚠️ Warning: Could not patch YOLOX blocks: {e}") + + print("✅ Monkey Patch: All NPU hooks applied.") + +# ========================================== +# 6. 模型加载逻辑 +# ========================================== +_NPU_MODEL_CACHE = {} +_CPU_MODEL_CACHE = {} +_ORIGINAL_GET_MODEL = None +_ORIGINAL_YOLOX_FORWARDS = {} + + +def _resolve_yolox_model_path(): + candidates = [ + os.environ.get("NPU_ADAPTER_YOLOX_MODEL_PATH", "").strip(), + os.environ.get("UNSTRUCTUREDIO_YOLOX_MODEL_PATH", "").strip(), + os.environ.get("YOLOX_MODEL_PATH", "").strip(), + "./yolox_l.pt", + "/models/unstructuredio/yolox_l.pt", + "/model/unstructuredio/yolox_l.pt", + ] + for candidate in candidates: + if candidate and os.path.exists(candidate): + return candidate + requested = next((candidate for candidate in candidates[:3] if candidate), "") + if requested: + raise FileNotFoundError(f"Configured YOLOX model file does not exist: {requested}") + raise FileNotFoundError( + "YOLOX model file was not found. Set NPU_ADAPTER_YOLOX_MODEL_PATH, " + "UNSTRUCTUREDIO_YOLOX_MODEL_PATH, or YOLOX_MODEL_PATH." + ) + + +def npu_get_model(model_name: str, **kwargs): + global _NPU_MODEL_CACHE + kwargs.pop('password', None) + + if os.environ.get("UNSTRUCTUREDIO_FORCE_CPU_MODELS") == "1": + return _cpu_get_model(model_name, **kwargs) + + if model_name in _NPU_MODEL_CACHE: + return _NPU_MODEL_CACHE[model_name] + + model_path = _resolve_yolox_model_path() + + print(f"[NPU Adapter] Loading local model: {model_path}") + + try: + from unstructured_inference.models.yolox import UnstructuredYoloXModel + except Exception: + if _ORIGINAL_GET_MODEL is not None: + return _ORIGINAL_GET_MODEL(model_name, **kwargs) + raise + model = UnstructuredYoloXModel() + model.model_path = model_path + + try: + ckpt = torch.load(model_path, map_location="cpu") + except Exception: + try: + ckpt = torch.jit.load(model_path, map_location="cpu") + except Exception as e: + print(f"❌ Error loading model: {e}") + raise FileNotFoundError(f"Model file not found or corrupted: {model_path}. Please download it.") + + if isinstance(ckpt, dict): + state_dict = ckpt.get("model", ckpt.get("state_dict", ckpt)) + else: + state_dict = ckpt.state_dict() if hasattr(ckpt, "state_dict") else ckpt + + from yolox.models import YOLOX, YOLOPAFPN, YOLOXHead + + num_classes = 5 + for k, v in state_dict.items(): + if "head.cls_preds" in k and hasattr(v, "shape"): + if v.shape[0] != num_classes: + num_classes = v.shape[0] + break + + def init_yolo(depth, width): + in_channels = [256, 512, 1024] + backbone = YOLOPAFPN(depth, width, in_channels=in_channels) + head = YOLOXHead(num_classes, width, in_channels=in_channels) + return YOLOX(backbone, head) + + model.model = init_yolo(1.0, 1.0) + model.model.load_state_dict(state_dict, strict=False) + model.model.eval() + optimize_model_for_npu(model.model) + + print("Moving model to NPU (FP32)...") + model.model.to("npu") + + print("[NPU Adapter] Model Ready.") + + _NPU_MODEL_CACHE[model_name] = model + return model + + +def _cpu_get_model(model_name: str, **kwargs): + global _CPU_MODEL_CACHE + kwargs.pop('password', None) + + if model_name in _CPU_MODEL_CACHE: + return _CPU_MODEL_CACHE[model_name] + + model_path = _resolve_yolox_model_path() + print(f"[NPU Adapter] Loading local CPU model: {model_path}") + + try: + from unstructured_inference.models.yolox import UnstructuredYoloXModel + except Exception: + if _ORIGINAL_GET_MODEL is not None: + return _ORIGINAL_GET_MODEL(model_name, **kwargs) + raise + model = UnstructuredYoloXModel() + model.model_path = model_path + + try: + ckpt = torch.load(model_path, map_location="cpu") + except Exception: + try: + ckpt = torch.jit.load(model_path, map_location="cpu") + except Exception as e: + print(f"Error loading CPU model: {e}") + if _ORIGINAL_GET_MODEL is not None: + return _ORIGINAL_GET_MODEL(model_name, **kwargs) + raise FileNotFoundError(f"Model file not found or corrupted: {model_path}. Please download it.") + + if isinstance(ckpt, dict): + state_dict = ckpt.get("model", ckpt.get("state_dict", ckpt)) + else: + state_dict = ckpt.state_dict() if hasattr(ckpt, "state_dict") else ckpt + + from yolox.models import YOLOX, YOLOPAFPN, YOLOXHead + + num_classes = 5 + for k, v in state_dict.items(): + if "head.cls_preds" in k and hasattr(v, "shape"): + if v.shape[0] != num_classes: + num_classes = v.shape[0] + break + + backbone = YOLOPAFPN(1.0, 1.0, in_channels=[256, 512, 1024]) + head = YOLOXHead(num_classes, 1.0, in_channels=[256, 512, 1024]) + model.model = YOLOX(backbone, head) + model.model.load_state_dict(state_dict, strict=False) + model.model.eval() + model.model.to("cpu") + _restore_original_yolox_forwards_for_cpu_model(model.model) + _CPU_MODEL_CACHE[model_name] = model + return model + + +def _restore_original_yolox_forwards_for_cpu_model(model): + import types as _types + try: + from yolox.models.network_blocks import Focus, Bottleneck, CSPLayer, SPPBottleneck + from yolox.models.yolo_pafpn import YOLOPAFPN + from yolox.models.yolo_head import YOLOXHead + except Exception: + return + + class_to_key = { + Focus: "Focus", + Bottleneck: "Bottleneck", + CSPLayer: "CSPLayer", + SPPBottleneck: "SPPBottleneck", + YOLOPAFPN: "YOLOPAFPN", + YOLOXHead: "YOLOXHead", + } + for module in model.modules(): + for cls, key in class_to_key.items(): + if isinstance(module, cls) and key in _ORIGINAL_YOLOX_FORWARDS: + module.forward = _types.MethodType(_ORIGINAL_YOLOX_FORWARDS[key], module) + if isinstance(module, YOLOXHead) and "YOLOXHead.decode_outputs" in _ORIGINAL_YOLOX_FORWARDS: + module.decode_outputs = _types.MethodType( + _ORIGINAL_YOLOX_FORWARDS["YOLOXHead.decode_outputs"], + module, + ) + +# ========================================== +# 7. 推理逻辑重写 +# ========================================== +def _local_yolox_preprocess(img, input_size, swap=(2, 0, 1)): + import cv2 + if len(img.shape) == 3: + padded_img = np.ones((input_size[0], input_size[1], 3), dtype=np.uint8) * 114 + else: + padded_img = np.ones(input_size, dtype=np.uint8) * 114 + + r = min(input_size[0] / img.shape[0], input_size[1] / img.shape[1]) + resized_img = cv2.resize( + img, + (int(img.shape[1] * r), int(img.shape[0] * r)), + interpolation=cv2.INTER_LINEAR, + ).astype(np.uint8) + + padded_img[: int(img.shape[0] * r), : int(img.shape[1] * r)] = resized_img + padded_img = padded_img.transpose(swap) + padded_img = np.ascontiguousarray(padded_img, dtype=np.float32) + return padded_img, r + +def npu_yolox_predict(self, x: np.ndarray): + if not isinstance(x, np.ndarray): + x = np.asarray(x) + + force_cpu = os.environ.get("UNSTRUCTUREDIO_FORCE_CPU_MODELS") == "1" + target_device = "cpu" if force_cpu else "npu" + input_shape = (1024, 1024) + image_h, image_w = x.shape[:2] + preprocessed_img, ratio = _local_yolox_preprocess(x, input_shape) + + input_tensor = torch.from_numpy(preprocessed_img).unsqueeze(0).to(target_device) + + with torch.no_grad(): + if not force_cpu: + torch.npu.synchronize() + outputs = self.model(input_tensor) + if not force_cpu: + torch.npu.synchronize() + + raw_out = outputs.get("det", outputs.get("dets")) if isinstance(outputs, dict) else outputs + + if raw_out is not None: + decoder_outputs = raw_out.float().cpu() + decoder_outputs = torch.nan_to_num(decoder_outputs, nan=0.0, posinf=10000.0, neginf=0.0) + predictions = decoder_outputs[0] + else: + predictions = None + + if predictions is None: + return NpuLayoutElements([]) + + boxes_xywh = predictions[:, :4] + boxes_xyxy = torch.empty_like(boxes_xywh) + boxes_xyxy[:, 0] = boxes_xywh[:, 0] - boxes_xywh[:, 2] / 2.0 + boxes_xyxy[:, 1] = boxes_xywh[:, 1] - boxes_xywh[:, 3] / 2.0 + boxes_xyxy[:, 2] = boxes_xywh[:, 0] + boxes_xywh[:, 2] / 2.0 + boxes_xyxy[:, 3] = boxes_xywh[:, 1] + boxes_xywh[:, 3] / 2.0 + obj_scores = predictions[:, 4:5] + cls_scores = predictions[:, 5:] + + cls_max_scores, cls_ids = cls_scores.max(1, keepdim=True) + final_scores = obj_scores * cls_max_scores + + conf_thr = 0.1 + mask = final_scores.squeeze() > conf_thr + + filtered_boxes = boxes_xyxy[mask] + filtered_scores = final_scores[mask].squeeze() + filtered_cls_ids = cls_ids[mask].squeeze() + + if len(filtered_boxes) == 0: + return NpuLayoutElements([]) + + nms_thr = 0.45 + keep_indices = nms(filtered_boxes, filtered_scores, nms_thr) + + final_boxes = filtered_boxes[keep_indices] + final_scores = filtered_scores[keep_indices] + final_cls_ids = filtered_cls_ids[keep_indices] + + final_boxes /= ratio + + # 将坐标约束到原图边界内,并修正可能出现的颠倒坐标 + x1 = torch.minimum(final_boxes[:, 0], final_boxes[:, 2]).clamp(0.0, float(image_w)) + y1 = torch.minimum(final_boxes[:, 1], final_boxes[:, 3]).clamp(0.0, float(image_h)) + x2 = torch.maximum(final_boxes[:, 0], final_boxes[:, 2]).clamp(0.0, float(image_w)) + y2 = torch.maximum(final_boxes[:, 1], final_boxes[:, 3]).clamp(0.0, float(image_h)) + final_boxes = torch.stack([x1, y1, x2, y2], dim=1) + + valid_mask = (final_boxes[:, 2] - final_boxes[:, 0] > 1.0) & (final_boxes[:, 3] - final_boxes[:, 1] > 1.0) + final_boxes = final_boxes[valid_mask] + final_scores = final_scores[valid_mask] + final_cls_ids = final_cls_ids[valid_mask] + + if len(final_boxes) == 0: + return NpuLayoutElements([]) + + from unstructured_inference.inference.layoutelement import LayoutElement + elements_list = [] + + label_map = { + 0: "Caption", 1: "Footnote", 2: "Formula", 3: "List-item", + 4: "Page-footer", 5: "Page-header", 6: "Picture", 7: "Section-header", + 8: "Table", 9: "Text", 10: "Title" + } + + for box, score, cls_id in zip(final_boxes, final_scores, final_cls_ids): + x1, y1, x2, y2 = box.numpy() + label = label_map.get(int(cls_id.item()), "Text") + elements_list.append(LayoutElement.from_coords(x1, y1, x2, y2, text=None, type=label, prob=score.item())) + + return NpuLayoutElements(elements_list) + +# 【核心修复】兼容当前 unstructured_inference 版本的 PageLayout.from_image +def npu_pagelayout_from_image( + cls, + image, + image_path=None, + document_filename=None, + number=1, + detection_model=None, + element_extraction_model=None, + layout=None, + extract_tables=False, + fixed_layout=None, + extract_images_in_pdf=False, + image_output_dir_path=None, + analysis=False, + **kwargs, +): + if detection_model is None: + from unstructured_inference.models.base import get_model + detection_model = get_model("yolox", **kwargs) + + init_kwargs = { + "number": number, + "image": image, + "detection_model": detection_model, + "element_extraction_model": element_extraction_model, + } + supported_params = set(inspect.signature(cls.__init__).parameters) + if "layout" in supported_params: + init_kwargs["layout"] = layout + if "extract_tables" in supported_params: + init_kwargs["extract_tables"] = extract_tables + if "analysis" in supported_params: + init_kwargs["analysis"] = analysis + if "image_path" in supported_params: + init_kwargs["image_path"] = image_path + if "document_filename" in supported_params: + init_kwargs["document_filename"] = document_filename + + page = cls(**init_kwargs) + + if element_extraction_model is not None: + page.get_elements_using_image_extraction() + elif fixed_layout is not None: + if hasattr(page, "get_elements_from_layout"): + page.elements = page.get_elements_from_layout(fixed_layout) + else: + page.elements = fixed_layout + elif hasattr(page, "get_elements_with_detection_model"): + page.get_elements_with_detection_model() + else: + inferred_layout = detection_model.predict(np.array(image)) + try: + inferred_layout = detection_model.deduplicate_detected_elements(inferred_layout) + except Exception: + pass + if hasattr(page, "get_elements_from_layout"): + page.elements = page.get_elements_from_layout(inferred_layout) + else: + page.elements = inferred_layout + if analysis: + page.inferred_layout = inferred_layout + + _sync_page_layout_arrays(page) + + page.image_metadata = { + "format": page.image.format if page.image else None, + "width": page.image.width if page.image else None, + "height": page.image.height if page.image else None, + } + page.image_path = os.path.abspath(image_path) if image_path else None + page.document_filename = os.path.abspath(document_filename) if document_filename else None + + if extract_images_in_pdf: + page.extract_images(image_output_dir_path) + + # 与原始实现保持一致,释放图片内存 + page.image = None + return page diff --git a/runtime/ops/mapper/unstructuredio/operator_src/adapters/ocr_npu_adapter.py b/runtime/ops/mapper/unstructuredio/operator_src/adapters/ocr_npu_adapter.py new file mode 100644 index 00000000..918854d1 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/adapters/ocr_npu_adapter.py @@ -0,0 +1,815 @@ +import atexit +import importlib +import importlib.machinery +import importlib.util +import collections +import collections.abc +import multiprocessing +import os +import sys +import threading +import time +import types +import warnings + +import numpy as np +import pandas as pd + +DEFAULT_MODEL_ROOT = os.environ.get("OCR_ADAPTER_MODEL_ROOT", "/root/.paddlex/official_models") +DEFAULT_CPU_DEVICE = "cpu" +DEFAULT_NPU_DEVICE = "npu" +DEFAULT_CPU_ISOLATION_ROOT = os.environ.get( + "OCR_ADAPTER_CPU_CUSTOM_DEVICE_ROOT", + "/tmp/dummy_empty_dir_for_isolation", +) +DEFAULT_LIBGOMP_PATH = os.environ.get( + "OCR_ADAPTER_LIBGOMP_PATH", + "/lib/aarch64-linux-gnu/libgomp.so.1", +) +DEFAULT_TORCH_LIBGOMP_PATH = os.environ.get( + "OCR_ADAPTER_TORCH_LIBGOMP_PATH", + "/usr/local/lib/python3.10/dist-packages/torch.libs/libgomp-6e1a1d1b.so.1.0.0", +) +DEFAULT_WORKER_INIT_TIMEOUT = int(os.environ.get("OCR_ADAPTER_INIT_TIMEOUT", "300")) +DEFAULT_WORKER_REQUEST_TIMEOUT = int(os.environ.get("OCR_ADAPTER_REQUEST_TIMEOUT", "180")) +ASCEND_NPU_LIBRARY_PATHS = ( + "/usr/local/Ascend/nnal/asdsip/8.5.1/lib", + "/usr/local/Ascend/nnal/atb/8.5.1/atb/cxx_abi_0/lib", + "/usr/local/Ascend/nnal/atb/latest/atb/cxx_abi_1/lib", + "/usr/local/Ascend/nnal/asdsip/latest/lib", + "/usr/local/Ascend/cann-8.5.1/lib64", + "/usr/local/Ascend/cann-8.5.1/aarch64-linux/lib64", + "/usr/local/Ascend/cann-8.5.1/aarch64-linux/devlib", + "/usr/local/Ascend/ascend-toolkit/latest/lib64", + "/usr/local/Ascend/ascend-toolkit/latest/aarch64-linux/lib64", + "/usr/local/Ascend/driver/lib64", + "/usr/local/Ascend/driver/lib64/driver", + "/usr/local/Ascend/driver/lib64/common", +) + +_REAL_PYTESSERACT = None +_REAL_UNSTRUCTURED_PYTESSERACT = None + + +def _patch_legacy_collections_aliases(): + for name in ("Mapping", "MutableMapping", "Sequence"): + if not hasattr(collections, name): + setattr(collections, name, getattr(collections.abc, name)) + + +def _normalize_device(device): + return DEFAULT_NPU_DEVICE if str(device).strip().lower() == DEFAULT_NPU_DEVICE else DEFAULT_CPU_DEVICE + + +def _env_flag(name, default=False): + value = os.environ.get(name) + if value is None: + return default + return value.strip().lower() in {"1", "true", "yes", "on"} + + +def _native_fallback_disabled(): + return _env_flag("OCR_ADAPTER_DISABLE_NATIVE_FALLBACK", False) + + +def _select_mp_context_name(device): + requested = os.environ.get("OCR_ADAPTER_MP_CONTEXT") + return requested or "fork" + + +def _worker_env_overrides(device): + env = { + "OCR_ADAPTER_WORKER": "1", + "OCR_ADAPTER_DEVICE": device, + "OMP_NUM_THREADS": "1", + "MKL_NUM_THREADS": "1", + "Paddle_OP_PARALLELISM_THREADS": "1", + "FLAGS_allocator_strategy": "naive_best_fit", + "FLAGS_fraction_of_gpu_memory_to_use": "0", + "FLAGS_use_system_allocator": "1", + "PADDLE_PDX_DISABLE_MODEL_SOURCE_CHECK": "True", + } + if device == DEFAULT_CPU_DEVICE: + os.makedirs(DEFAULT_CPU_ISOLATION_ROOT, exist_ok=True) + env.update( + { + "CUSTOM_DEVICE_ROOT": DEFAULT_CPU_ISOLATION_ROOT, + "CUDA_VISIBLE_DEVICES": "", + "ASCEND_VISIBLE_DEVICES": "", + "ASCEND_RT_VISIBLE_DEVICES": "", + } + ) + else: + env["CUSTOM_DEVICE_ROOT"] = "" + return env + + +def _safe_int(name, default): + value = os.environ.get(name) + if value is None: + return default + try: + return int(value) + except ValueError: + return default + + +def _resolve_model(kind): + if kind == "det": + name_env = "OCR_ADAPTER_TEXT_DET_MODEL_NAME" + dir_env = "OCR_ADAPTER_TEXT_DET_MODEL_DIR" + default_name = "PP-OCRv4_mobile_det" + elif kind == "rec": + name_env = "OCR_ADAPTER_TEXT_REC_MODEL_NAME" + dir_env = "OCR_ADAPTER_TEXT_REC_MODEL_DIR" + default_name = "PP-OCRv4_mobile_rec" + else: + raise ValueError(f"Unknown model kind: {kind}") + + model_name = os.environ.get(name_env, default_name).strip() + explicit_dir = os.environ.get(dir_env) + if explicit_dir and os.path.isdir(explicit_dir): + return model_name, explicit_dir + + candidate_dir = os.path.join(DEFAULT_MODEL_ROOT, model_name) + if model_name and os.path.isdir(candidate_dir): + return model_name, candidate_dir + + return model_name, explicit_dir or None + + +def _build_paddleocr_init_kwargs(device): + det_name, det_dir = _resolve_model("det") + rec_name, rec_dir = _resolve_model("rec") + try: + from paddleocr import VERSION as paddleocr_version + except Exception: + paddleocr_version = "" + is_legacy_paddleocr = str(paddleocr_version).startswith("2.") + kwargs = { + "lang": os.environ.get("OCR_ADAPTER_LANG", "ch"), + "show_log": False, + "use_angle_cls": False, + } + if not is_legacy_paddleocr: + kwargs.update( + { + "use_doc_orientation_classify": False, + "use_doc_unwarping": False, + "use_textline_orientation": False, + } + ) + + if det_name and not is_legacy_paddleocr: + kwargs["text_detection_model_name"] = det_name + if det_dir: + if not is_legacy_paddleocr: + kwargs["text_detection_model_dir"] = det_dir + kwargs["det_model_dir"] = det_dir + if rec_name and not is_legacy_paddleocr: + kwargs["text_recognition_model_name"] = rec_name + if rec_dir: + if not is_legacy_paddleocr: + kwargs["text_recognition_model_dir"] = rec_dir + kwargs["rec_model_dir"] = rec_dir + cls_dir = os.environ.get("OCR_ADAPTER_TEXT_CLS_MODEL_DIR") + if cls_dir and os.path.isdir(cls_dir): + kwargs["cls_model_dir"] = cls_dir + + if device == DEFAULT_CPU_DEVICE: + kwargs["enable_mkldnn"] = _env_flag("OCR_ADAPTER_ENABLE_MKLDNN", True) + kwargs["cpu_threads"] = _safe_int("OCR_ADAPTER_CPU_THREADS", 1) + kwargs["use_gpu"] = False + else: + if not is_legacy_paddleocr: + kwargs["device"] = device + kwargs["use_gpu"] = False + kwargs["use_npu"] = True + + model_desc = f"det={det_dir or det_name}, rec={rec_dir or rec_name}" + return kwargs, model_desc + + +def _configure_worker_env(device): + os.environ["OMP_NUM_THREADS"] = "1" + os.environ["MKL_NUM_THREADS"] = "1" + os.environ["Paddle_OP_PARALLELISM_THREADS"] = "1" + os.environ["FLAGS_allocator_strategy"] = "naive_best_fit" + os.environ["FLAGS_fraction_of_gpu_memory_to_use"] = "0" + os.environ["FLAGS_use_system_allocator"] = "1" + os.environ["PADDLE_PDX_DISABLE_MODEL_SOURCE_CHECK"] = "True" + + if device == DEFAULT_CPU_DEVICE: + os.makedirs(DEFAULT_CPU_ISOLATION_ROOT, exist_ok=True) + os.environ["CUSTOM_DEVICE_ROOT"] = DEFAULT_CPU_ISOLATION_ROOT + os.environ["CUDA_VISIBLE_DEVICES"] = "" + os.environ["ASCEND_VISIBLE_DEVICES"] = "" + os.environ["ASCEND_RT_VISIBLE_DEVICES"] = "" + else: + os.environ.pop("CUSTOM_DEVICE_ROOT", None) + _prepend_ld_library_paths(ASCEND_NPU_LIBRARY_PATHS) + + +def _prepend_ld_library_paths(paths): + current = [part for part in os.environ.get("LD_LIBRARY_PATH", "").split(":") if part] + merged = [] + for path in list(paths) + current: + if path and os.path.exists(path) and path not in merged: + merged.append(path) + if merged: + os.environ["LD_LIBRARY_PATH"] = ":".join(merged) + + +def _merge_ld_preload(): + current = os.environ.get("LD_PRELOAD", "") + parts = [part for part in current.split(":") if part] + for candidate in (DEFAULT_TORCH_LIBGOMP_PATH, DEFAULT_LIBGOMP_PATH): + if os.path.exists(candidate) and candidate not in parts: + parts.insert(0, candidate) + return ":".join(parts) + + +def _load_native_tesseract_modules(): + global _REAL_PYTESSERACT, _REAL_UNSTRUCTURED_PYTESSERACT + + if _REAL_PYTESSERACT is None: + _REAL_PYTESSERACT = importlib.import_module("pytesseract") + + if _REAL_UNSTRUCTURED_PYTESSERACT is None: + try: + _REAL_UNSTRUCTURED_PYTESSERACT = importlib.import_module("unstructured_pytesseract") + except ImportError: + _REAL_UNSTRUCTURED_PYTESSERACT = _REAL_PYTESSERACT + + +def _prefer_native_cpu_ocr(): + return ( + _normalize_device(os.environ.get("OCR_ADAPTER_DEVICE", DEFAULT_CPU_DEVICE)) == DEFAULT_CPU_DEVICE + and not _env_flag("OCR_ADAPTER_FORCE_PADDLE_CPU", False) + ) + + +def _paddle_ocr_available(): + try: + if _normalize_device(os.environ.get("OCR_ADAPTER_DEVICE", DEFAULT_CPU_DEVICE)) == DEFAULT_NPU_DEVICE: + return importlib.util.find_spec("paddle") is not None and importlib.util.find_spec("paddleocr") is not None + else: + # Do not import Paddle in the parent process for CPU OCR. In mixed + # Torch-NPU + PaddleOCR runs, importing Paddle here may load the + # custom NPU plugin before the worker has isolated CUSTOM_DEVICE_ROOT. + return importlib.util.find_spec("paddle") is not None and importlib.util.find_spec("paddleocr") is not None + except ImportError: + return False + + +def _native_pytesseract_module(): + return _REAL_UNSTRUCTURED_PYTESSERACT or _REAL_PYTESSERACT + + +def _map_native_output_type(output_type): + native_mod = _native_pytesseract_module() + if native_mod is None: + return output_type + + output_map = { + None: None, + _ImplOutput.DATAFRAME: native_mod.Output.DATAFRAME, + "data.frame": native_mod.Output.DATAFRAME, + _ImplOutput.DICT: native_mod.Output.DICT, + "dict": native_mod.Output.DICT, + _ImplOutput.STRING: native_mod.Output.STRING, + "string": native_mod.Output.STRING, + } + + if hasattr(native_mod.Output, "BYTES"): + output_map[_ImplOutput.BYTES] = native_mod.Output.BYTES + output_map["bytes"] = native_mod.Output.BYTES + + return output_map.get(output_type, output_type) + + +def _native_image_to_data(image, lang=None, output_type=None, **kwargs): + native_mod = _native_pytesseract_module() + if native_mod is None: + raise _ImplTesseractNotFoundError("原生 pytesseract 不可用") + + native_output_type = _map_native_output_type(output_type) + return native_mod.image_to_data( + image, + lang=lang, + output_type=native_output_type, + **kwargs, + ) + + +def _native_image_to_string(image, lang=None, **kwargs): + native_mod = _native_pytesseract_module() + if native_mod is None: + raise _ImplTesseractNotFoundError("原生 pytesseract 不可用") + return native_mod.image_to_string(image, lang=lang, **kwargs) + + +def _native_image_to_pdf(image, **kwargs): + native_mod = _native_pytesseract_module() + if native_mod is None: + raise _ImplTesseractNotFoundError("原生 pytesseract 不可用") + return native_mod.image_to_pdf_or_hocr(image, **kwargs) + + +def _legacy_paddle_from_tesseract(image, lang=None, **kwargs): + data = _native_image_to_data(image, lang=lang, output_type=_ImplOutput.DICT, **kwargs) or {} + texts = data.get("text", []) or [] + lefts = data.get("left", []) or [] + tops = data.get("top", []) or [] + widths = data.get("width", []) or [] + heights = data.get("height", []) or [] + confs = data.get("conf", []) or [] + + page_lines = [] + for idx, text in enumerate(texts): + text = str(text or "").strip() + if not text: + continue + + try: + conf = float(confs[idx]) if idx < len(confs) else -1.0 + except (TypeError, ValueError): + conf = -1.0 + if conf < 0: + continue + + x = int(float(lefts[idx])) if idx < len(lefts) else 0 + y = int(float(tops[idx])) if idx < len(tops) else 0 + w = int(float(widths[idx])) if idx < len(widths) else 0 + h = int(float(heights[idx])) if idx < len(heights) else 0 + quad = [ + [x, y], + [x + w, y], + [x + w, y + h], + [x, y + h], + ] + page_lines.append([quad, (text, conf / 100.0)]) + + return [page_lines] + + +def _iter_ocr_lines(result): + if not result: + return + + first_item = result[0] + if isinstance(first_item, dict): + for page in result: + texts = page.get("rec_texts") or [] + scores = page.get("rec_scores") or [] + polys = page.get("rec_polys") or page.get("dt_polys") or [] + boxes = page.get("rec_boxes") + + for idx, text in enumerate(texts): + if not text: + continue + + conf = float(scores[idx]) if idx < len(scores) and scores[idx] is not None else 0.0 + box = None + if idx < len(polys): + box = polys[idx] + elif boxes is not None and idx < len(boxes): + box = boxes[idx] + yield box, str(text), conf + return + + if isinstance(first_item, list): + for line in first_item: + if not line: + continue + try: + box, (text, conf) = line + except (TypeError, ValueError): + continue + if text: + yield box, str(text), float(conf) + + +def _to_quad(box): + if box is None: + return None + + if hasattr(box, "tolist"): + box = box.tolist() + + if not box: + return None + + if len(box) == 4 and not isinstance(box[0], (list, tuple)): + x1, y1, x2, y2 = [float(v) for v in box] + return [ + [x1, y1], + [x2, y1], + [x2, y2], + [x1, y2], + ] + + quad = [] + for point in box: + if hasattr(point, "tolist"): + point = point.tolist() + if not isinstance(point, (list, tuple)) or len(point) < 2: + continue + quad.append([float(point[0]), float(point[1])]) + return quad or None + + +def _box_to_xywh(box): + quad = _to_quad(box) + if not quad: + return 0, 0, 0, 0 + + xs = [pt[0] for pt in quad] + ys = [pt[1] for pt in quad] + x_min = int(min(xs)) + y_min = int(min(ys)) + width = int(max(xs) - x_min) + height = int(max(ys) - y_min) + return x_min, y_min, width, height + + +def _result_to_legacy_paddle(result): + if not result: + return [[]] + + first_item = result[0] + if isinstance(first_item, list): + return result + + legacy_pages = [] + for page in result: + page_lines = [] + texts = page.get("rec_texts") or [] + scores = page.get("rec_scores") or [] + polys = page.get("rec_polys") or page.get("dt_polys") or [] + boxes = page.get("rec_boxes") + + for idx, text in enumerate(texts): + if not text: + continue + + conf = float(scores[idx]) if idx < len(scores) and scores[idx] is not None else 0.0 + if idx < len(polys): + quad = _to_quad(polys[idx]) + elif boxes is not None and idx < len(boxes): + quad = _to_quad(boxes[idx]) + else: + quad = None + + if quad: + page_lines.append([quad, (str(text), conf)]) + + legacy_pages.append(page_lines) + + return legacy_pages or [[]] + +# ========================================== +# 0. Worker Process Logic (Isolated Environment) +# ========================================== +def _paddle_worker_main(in_queue, out_queue): + """ + Runs in a completely separate process. + PREVENTS Paddle from loading the NPU plugin to avoid memory conflicts. + """ + device = _normalize_device(os.environ.get("OCR_ADAPTER_DEVICE", DEFAULT_CPU_DEVICE)) + _configure_worker_env(device) + + try: + warnings.filterwarnings("ignore") + _patch_legacy_collections_aliases() + init_kwargs, model_desc = _build_paddleocr_init_kwargs(device) + + if device == DEFAULT_NPU_DEVICE: + from paddleocr import PaddleOCR + + ocr_engine = PaddleOCR(**init_kwargs) + else: + import paddle + from paddleocr import PaddleOCR + + paddle.disable_signal_handler() + paddle.set_device(DEFAULT_CPU_DEVICE) + ocr_engine = PaddleOCR(**init_kwargs) + + out_queue.put(("INIT_SUCCESS", f"{device.upper()} Mode [{model_desc}]")) + + while True: + task = in_queue.get() + if task is None: + break + req_id, img_array = task + try: + if not isinstance(img_array, np.ndarray): + img_array = np.array(img_array) + result = _result_to_legacy_paddle(ocr_engine.ocr(img_array)) + out_queue.put((req_id, "OK", result)) + except Exception as e: + out_queue.put((req_id, "ERROR", str(e))) + + except Exception as e: + out_queue.put(("INIT_ERROR", f"Worker Crash: {str(e)}")) + +# ========================================== +# 1. OCR Client (Main Process) +# ========================================== +class PaddleOCRInference: + _instance = None + + def __init__(self): + self.device = _normalize_device(os.environ.get("OCR_ADAPTER_DEVICE", DEFAULT_CPU_DEVICE)) + self.native_only = _prefer_native_cpu_ocr() + self.last_error = "" + if not self.native_only and not _paddle_ocr_available(): + self.native_only = True + self.is_alive = False + self.last_error = "PaddleOCR dependencies are unavailable; using native OCR fallback" + print(f"\033[93m[OCR Adapter] {self.last_error}\033[0m") + atexit.register(self.kill) + return + + self.ctx = multiprocessing.get_context(_select_mp_context_name(self.device)) + self.in_q = self.ctx.Queue() + self.out_q = self.ctx.Queue() + self.lock = threading.Lock() + self.is_alive = False + + if self.native_only: + print( + "\n\033[94m[OCR Adapter] CPU 模式下直接回退原生 pytesseract," + "避免 Paddle OCR 兼容性风险。\033[0m" + ) + atexit.register(self.kill) + return + + print( + f"\n\033[94m[OCR Adapter] Spawning isolated OCR process " + f"({self.device.upper()} Mode)...\033[0m" + ) + + env_overrides = _worker_env_overrides(self.device) + preload_value = _merge_ld_preload() + if preload_value: + env_overrides["LD_PRELOAD"] = preload_value + + previous_env = {key: os.environ.get(key) for key in env_overrides} + for key, value in env_overrides.items(): + if value == "": + os.environ.pop(key, None) + else: + os.environ[key] = value + + self.process = self.ctx.Process( + target=_paddle_worker_main, + args=(self.in_q, self.out_q), + ) + self.process.daemon = True + try: + self.process.start() + finally: + for key, old_value in previous_env.items(): + if old_value is None: + os.environ.pop(key, None) + else: + os.environ[key] = old_value + + try: + status, msg = self.out_q.get(timeout=DEFAULT_WORKER_INIT_TIMEOUT) + if status == "INIT_SUCCESS": + print(f"\033[92m[OCR Adapter] OCR Process Ready. [{msg}]\033[0m") + self.is_alive = True + self.last_error = "" + else: + print(f"\033[91m[OCR Adapter] Worker Init Failed: {msg}\033[0m") + self.last_error = str(msg) + self.kill() + except Exception as e: + print(f"\033[91m[OCR Adapter] Worker Timeout/Error: {e}\033[0m") + self.last_error = str(e) + self.kill() + + atexit.register(self.kill) + + def kill(self): + if hasattr(self, "process") and self.process.is_alive(): + self.in_q.put(None) + self.process.join(timeout=10) + if self.process.is_alive(): + self.process.terminate() + self.is_alive = False + + def ocr(self, img_array): + if self.native_only or not self.is_alive: + return None + + with self.lock: + req_id = time.time() + try: + self.in_q.put((req_id, img_array)) + resp_id, status, data = self.out_q.get(timeout=DEFAULT_WORKER_REQUEST_TIMEOUT) + if resp_id != req_id: + self.last_error = "OCR worker response id mismatch" + return None + if status == "ERROR": + self.last_error = str(data) + return None + self.last_error = "" + return data + except Exception: + self.is_alive = False + self.last_error = "OCR worker request failed" + return None + + @classmethod + def get_instance(cls): + if cls._instance is None: + cls._instance = PaddleOCRInference() + return cls._instance + + +def get_ocr_runtime_status(): + instance = PaddleOCRInference.get_instance() + return { + "available": bool(getattr(instance, "is_alive", False)) and not bool(getattr(instance, "native_only", True)), + "device": getattr(instance, "device", DEFAULT_CPU_DEVICE), + "native_only": bool(getattr(instance, "native_only", True)), + "is_alive": bool(getattr(instance, "is_alive", False)), + "last_error": getattr(instance, "last_error", ""), + } + + +class UnstructuredPaddleOCRProxy: + def __init__(self, *args, **kwargs): + self.client = PaddleOCRInference.get_instance() + + def ocr(self, img_array, cls=False, **kwargs): + lang = kwargs.get("lang") + if self.client.native_only: + if _native_fallback_disabled(): + raise RuntimeError("OCR native fallback is disabled") + return _legacy_paddle_from_tesseract(np.array(img_array), lang=lang) + + result = self.client.ocr(np.array(img_array)) + if result is None: + if _native_fallback_disabled(): + raise RuntimeError("OCR NPU inference failed and native fallback is disabled") + return _legacy_paddle_from_tesseract(np.array(img_array), lang=lang) + return _result_to_legacy_paddle(result) + + predict = ocr + + +# ========================================== +# 2. Logic Implementation +# ========================================== +def _impl_paddle_to_data(image_array): + client = PaddleOCRInference.get_instance() + if client.native_only: + if _native_fallback_disabled(): + raise RuntimeError("OCR native fallback is disabled") + return _native_image_to_data(image_array, output_type=_ImplOutput.DATAFRAME) + + result = client.ocr(image_array) + if result is None: + if _native_fallback_disabled(): + raise RuntimeError("OCR NPU inference failed and native fallback is disabled") + return _native_image_to_data(image_array, output_type=_ImplOutput.DATAFRAME) + + data = { + 'level': [], 'page_num': [], 'block_num': [], 'par_num': [], + 'line_num': [], 'word_num': [], 'left': [], 'top': [], + 'width': [], 'height': [], 'conf': [], 'text': [] + } + + if not result or result[0] is None: + return pd.DataFrame(data) + + for idx, (box, text, conf) in enumerate(_iter_ocr_lines(result)): + x_min, y_min, width, height = _box_to_xywh(box) + data["level"].append(5) + data["page_num"].append(1) + data["block_num"].append(1) + data["par_num"].append(1) + data["line_num"].append(idx + 1) + data["word_num"].append(1) + data["left"].append(x_min) + data["top"].append(y_min) + data["width"].append(width) + data["height"].append(height) + data["conf"].append(conf * 100) + data["text"].append(text) + return pd.DataFrame(data) + + +def _impl_image_to_data(image, lang=None, output_type=None, **kwargs): + img_array = np.array(image) + client = PaddleOCRInference.get_instance() + if client.native_only or not client.is_alive: + if _native_fallback_disabled(): + raise RuntimeError("OCR native fallback is disabled") + return _native_image_to_data(image, lang=lang, output_type=output_type, **kwargs) + + df = _impl_paddle_to_data(img_array) + if output_type in (_ImplOutput.DATAFRAME, "data.frame"): + return df + if output_type in (_ImplOutput.DICT, "dict"): + return df.to_dict(orient="list") + return df.to_csv(sep="\t", index=False) + + +def _impl_image_to_string(image, lang=None, **kwargs): + img_array = np.array(image) + client = PaddleOCRInference.get_instance() + if client.native_only: + if _native_fallback_disabled(): + raise RuntimeError("OCR native fallback is disabled") + return _native_image_to_string(image, lang=lang, **kwargs) + + result = client.ocr(img_array) + if result is None: + if _native_fallback_disabled(): + raise RuntimeError("OCR NPU inference failed and native fallback is disabled") + return _native_image_to_string(image, lang=lang, **kwargs) + if not result or result[0] is None: + return "" + + lines = [text for _, text, _ in _iter_ocr_lines(result)] + return "\n".join(lines) + + +def _impl_image_to_pdf(image, **kwargs): + client = PaddleOCRInference.get_instance() + if client.native_only or not client.is_alive: + if _native_fallback_disabled(): + raise RuntimeError("OCR native fallback is disabled") + try: + return _native_image_to_pdf(image, **kwargs) + except Exception: + return b"" + return b"" + + +class _ImplOutput: + BYTES = "bytes" + DATAFRAME = "data.frame" + DICT = "dict" + STRING = "string" + + +class _ImplTesseractNotFoundError(EnvironmentError): + pass + +# ========================================== +# 3. Apply Patch (Module Injection) +# ========================================== +def apply_ocr_patch(): + if not _native_fallback_disabled() and not _env_flag("OCR_ADAPTER_FORCE_PADDLE_CPU", False): + _load_native_tesseract_modules() + + fake_mod = types.ModuleType("pytesseract") + fake_mod.__file__ = "fake_pytesseract.py" + fake_mod.__path__ = [] + fake_mod.__spec__ = importlib.machinery.ModuleSpec( + name="pytesseract", + loader=None, + origin="fake_pytesseract.py", + ) + + fake_mod.image_to_data = _impl_image_to_data + fake_mod.image_to_string = _impl_image_to_string + fake_mod.image_to_pdf_or_hocr = _impl_image_to_pdf + fake_mod.Output = _ImplOutput + fake_mod.TesseractNotFoundError = _ImplTesseractNotFoundError + + fake_unstructured_paddleocr = types.ModuleType("unstructured_paddleocr") + fake_unstructured_paddleocr.__file__ = "fake_unstructured_paddleocr.py" + fake_unstructured_paddleocr.__path__ = [] + fake_unstructured_paddleocr.__spec__ = importlib.machinery.ModuleSpec( + name="unstructured_paddleocr", + loader=None, + origin="fake_unstructured_paddleocr.py", + ) + fake_unstructured_paddleocr.PaddleOCR = UnstructuredPaddleOCRProxy + + sys.modules["pytesseract"] = fake_mod + sys.modules["unstructured_pytesseract"] = fake_mod + sys.modules["unstructured_paddleocr"] = fake_unstructured_paddleocr + + modules_to_patch = [ + "unstructured.partition.ocr", + "unstructured.partition.utils.ocr_models", + ] + for mod_name in modules_to_patch: + if mod_name in sys.modules: + try: + sys.modules[mod_name].pytesseract = fake_mod + except AttributeError: + pass + try: + sys.modules[mod_name].unstructured_pytesseract = fake_mod + except AttributeError: + pass diff --git a/runtime/ops/mapper/unstructuredio/operator_src/adapters/requirements_npu_v1.2_stable.txt b/runtime/ops/mapper/unstructuredio/operator_src/adapters/requirements_npu_v1.2_stable.txt new file mode 100644 index 00000000..98ad8c5b --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/adapters/requirements_npu_v1.2_stable.txt @@ -0,0 +1,25 @@ +# 910b-jss 临时 NPU 验证环境关键依赖 +# 说明:该文件是验收环境参考,不建议由 DataMate 算子上传包在运行时自动 pip install。 + +unstructured==0.18.32 +unstructured-inference==1.2.0 +torch==2.7.0 +torch-npu==2.7.1 +torchvision==0.22.0 +paddlepaddle==3.3.1 +paddle-custom-npu==3.3.0 +paddleocr==2.7.3 +numpy==1.26.4 +opencv-python-headless==4.9.0.80 +onnxruntime==1.23.2 +einops==0.8.2 +loguru==0.7.3 +pi_heif==1.0.0 +pikepdf==9.8.1 +pdf2image +pypdfium2 + +# 系统依赖 +# - Ascend CANN/driver runtime +# - poppler/pdf render dependencies required by unstructured/pdf2image +# - LibreOffice/soffice for DOCX/DOC strict NPU mode diff --git a/runtime/ops/mapper/unstructuredio/operator_src/check_npu_runtime.py b/runtime/ops/mapper/unstructuredio/operator_src/check_npu_runtime.py new file mode 100644 index 00000000..c77c138a --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/check_npu_runtime.py @@ -0,0 +1,129 @@ +from __future__ import annotations + +import importlib +import json +import os +import shutil +import subprocess +import sys +from pathlib import Path + +ASCEND_NPU_LIBRARY_PATHS = ( + "/usr/local/Ascend/nnal/asdsip/8.5.1/lib", + "/usr/local/Ascend/nnal/atb/8.5.1/atb/cxx_abi_0/lib", + "/usr/local/Ascend/nnal/atb/latest/atb/cxx_abi_1/lib", + "/usr/local/Ascend/nnal/asdsip/latest/lib", + "/usr/local/Ascend/cann-8.5.1/lib64", + "/usr/local/Ascend/cann-8.5.1/aarch64-linux/lib64", + "/usr/local/Ascend/cann-8.5.1/aarch64-linux/devlib", + "/usr/local/Ascend/cann-8.5.0/lib64", + "/usr/local/Ascend/cann-8.5.0/aarch64-linux/lib64", + "/usr/local/Ascend/cann-8.5.0/aarch64-linux/devlib", + "/usr/local/Ascend/ascend-toolkit/latest/lib64", + "/usr/local/Ascend/ascend-toolkit/latest/aarch64-linux/lib64", + "/usr/local/Ascend/driver/lib64", + "/usr/local/Ascend/driver/lib64/driver", + "/usr/local/Ascend/driver/lib64/common", +) + + +def _probe_env() -> dict[str, str]: + env = dict(os.environ) + current = [part for part in env.get("LD_LIBRARY_PATH", "").split(":") if part] + merged: list[str] = [] + for path in list(ASCEND_NPU_LIBRARY_PATHS) + current: + if path and os.path.exists(path) and path not in merged: + merged.append(path) + if merged: + env["LD_LIBRARY_PATH"] = ":".join(merged) + return env + + +def _module_version(name: str) -> dict[str, object]: + code = ( + "import importlib, json\n" + "try:\n" + f" module = importlib.import_module({name!r})\n" + " print(json.dumps({\n" + " 'available': True,\n" + " 'version': getattr(module, '__version__', getattr(module, 'VERSION', '')),\n" + " }, ensure_ascii=False))\n" + "except Exception as exc:\n" + " print(json.dumps({'available': False, 'error': f'{type(exc).__name__}: {exc}'}, ensure_ascii=False))\n" + " raise SystemExit(1)\n" + ) + proc = subprocess.run( + [sys.executable, "-c", code], + text=True, + capture_output=True, + check=False, + env=_probe_env(), + ) + output = (proc.stdout or "").strip().splitlines() + if output: + try: + return json.loads(output[-1]) + except json.JSONDecodeError: + pass + error = (proc.stderr or proc.stdout or "unknown import probe failure").strip() + return {"available": False, "error": error} + + +def _path_status(path: str | None) -> dict[str, object]: + if not path: + return {"configured": False, "exists": False} + resolved = Path(path) + return {"configured": True, "path": str(resolved), "exists": resolved.exists()} + + +def main() -> int: + model_root = os.getenv("UNSTRUCTUREDIO_OCR_MODEL_ROOT", "/models/unstructuredio/paddleocr") + report = { + "python_modules": { + "torch": _module_version("torch"), + "torch_npu": _module_version("torch_npu"), + "paddle": _module_version("paddle"), + "paddleocr": _module_version("paddleocr"), + "unstructured": _module_version("unstructured"), + "unstructured_inference": _module_version("unstructured_inference"), + }, + "models": { + "yolox_pt": _path_status( + os.getenv("UNSTRUCTUREDIO_YOLOX_MODEL_PATH", "/models/unstructuredio/yolox_l.pt") + ), + "yolox_src": _path_status( + os.getenv("UNSTRUCTUREDIO_YOLOX_SRC_PATH", "/models/unstructuredio/YOLOX-main") + ), + "ocr_det": _path_status( + os.getenv( + "UNSTRUCTUREDIO_OCR_DET_MODEL_DIR", + f"{model_root}/ch_PP-OCRv4_det_infer", + ) + ), + "ocr_rec": _path_status( + os.getenv( + "UNSTRUCTUREDIO_OCR_REC_MODEL_DIR", + f"{model_root}/ch_PP-OCRv4_rec_infer", + ) + ), + "ocr_cls": _path_status( + os.getenv( + "UNSTRUCTUREDIO_OCR_CLS_MODEL_DIR", + f"{model_root}/ch_ppocr_mobile_v2.0_cls_infer", + ) + ), + }, + "tools": { + "soffice": shutil.which("soffice") or shutil.which("libreoffice"), + }, + } + print(json.dumps(report, ensure_ascii=False, indent=2)) + + required_modules = ("torch", "torch_npu", "paddle", "paddleocr", "unstructured") + modules_ok = all(report["python_modules"][name]["available"] for name in required_modules) + models_ok = all(item["exists"] for item in report["models"].values()) + return 0 if modules_ok and models_ok else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/runtime/ops/mapper/unstructuredio/operator_src/metadata.yml b/runtime/ops/mapper/unstructuredio/operator_src/metadata.yml index 3d689355..e7d8c0e9 100644 --- a/runtime/ops/mapper/unstructuredio/operator_src/metadata.yml +++ b/runtime/ops/mapper/unstructuredio/operator_src/metadata.yml @@ -13,19 +13,19 @@ types: release: - '首次发布' - '支持 PDF、DOCX、DOC 及 unstructured 可识别文档格式' - - '输出 unstructured 兼容元素 JSON,并补充 DOCX 快路径与 PDF 噪声抑制' + - '输出 unstructured 兼容元素 JSON,并补充 NPU/OCR 优先路径、DOCX 快路径与 PDF 噪声抑制' metrics: - name: '输出形态' metric: 'unstructured-compatible JSON' - name: '表格保留' metric: '保留 Table / text_as_html 字段' - name: 'PDF 稳定性' - metric: '支持 fast/auto/hi_res 策略切换' + metric: '优先 NPU/OCR hi_res,失败后 fast/auto 自动回退' runtime: memory: 2147483648 cpu: 1 gpu: 0 - npu: 0 + npu: 1 settings: exportType: name: '导出格式' @@ -42,7 +42,7 @@ settings: value: 'txt' pdfStrategy: name: 'PDF 策略' - description: 'auto 最接近 unstructured 默认行为;fast 更快;hi_res 更重。' + description: '该参数用于 NPU/OCR 失败后的兜底策略;正常情况下优先走 NPU/OCR hi_res。' type: 'radio' defaultVal: 'auto' required: false @@ -54,13 +54,13 @@ settings: - label: 'HiRes' value: 'hi_res' pdfInferTableStructure: - name: 'PDF 琛ㄦ牸缁撴瀯' - description: '涓?PDF 寮€鍚?Table / text_as_html 鎺ㄦ柇锛屼紭鍏堜繚鎸?unstructured 杈撳嚭褰㈡€併€?' + name: 'PDF 表格结构' + description: '为 PDF 开启 Table / text_as_html 推断,优先保持 unstructured 输出形态。' type: 'switch' defaultVal: 'true' required: false - checkedLabel: '寮€鍚?' - unCheckedLabel: '鍏抽棴' + checkedLabel: '开启' + unCheckedLabel: '关闭' enableDocxFastpath: name: 'DOCX 快路径' description: '优先使用兼容型 DOCX 快路径,失败时自动回退到 unstructured 原生解析。' @@ -85,6 +85,14 @@ settings: required: false checkedLabel: '开启' unCheckedLabel: '关闭' + requireNpuModels: + name: '强制 NPU 模型链路' + description: '验收模式。开启后 PDF 必须使用 YOLOX PT NPU + PaddleOCR NPU;DOCX/DOC 先转 PDF 后走同一视觉 NPU 链路。任一 NPU 模型或 OCR NPU 不可用时直接失败,不回退 CPU。' + type: 'switch' + defaultVal: 'false' + required: false + checkedLabel: '开启' + unCheckedLabel: '关闭' jsonIndent: name: 'JSON 缩进' description: 'JSON 导出缩进空格数,默认 2。' diff --git a/runtime/ops/mapper/unstructuredio/operator_src/process.py b/runtime/ops/mapper/unstructuredio/operator_src/process.py index 282d4e85..f8652da9 100644 --- a/runtime/ops/mapper/unstructuredio/operator_src/process.py +++ b/runtime/ops/mapper/unstructuredio/operator_src/process.py @@ -1,15 +1,55 @@ from __future__ import annotations +import builtins import contextlib import html +import importlib.util import json import logging import os +import re +import shutil +import subprocess +import sys import tempfile import time +import zipfile from pathlib import Path from typing import Any, Dict, Iterable + +def _nltk_path_has_bad_zip(path: str | Path) -> bool: + root = Path(path) + if not root.exists(): + return False + for zip_path in root.rglob("*.zip"): + try: + with zipfile.ZipFile(zip_path) as archive: + archive.testzip() + except zipfile.BadZipFile: + return True + except OSError: + continue + return False + + +def _configure_nltk_import_environment() -> None: + # Avoid import-time downloads and corrupted global NLTK caches blocking PDF partition. + os.environ.setdefault("AUTO_DOWNLOAD_NLTK", "False") + preferred_paths = [ + os.getenv("UNSTRUCTUREDIO_NLTK_DATA", ""), + "/models/unstructuredio/nltk_data", + "/model/unstructuredio/nltk_data", + "/home/o_pengjunjie/huizhi/unstructuredio_models/nltk_data", + ] + for preferred in preferred_paths: + if preferred and Path(preferred).exists() and not _nltk_path_has_bad_zip(preferred): + os.environ["NLTK_DATA"] = preferred + break + + +_configure_nltk_import_environment() + from datamate.core.base_op import Mapper from unstructured.partition.auto import partition as partition_auto @@ -18,10 +58,7 @@ except ImportError: partition_doc = None -try: - from unstructured.partition.pdf import partition_pdf -except ImportError: - partition_pdf = None +partition_pdf = None try: from docx import Document @@ -40,6 +77,7 @@ logger = logging.getLogger(__name__) +OPERATOR_DIR = Path(__file__).resolve().parent W_NS = "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}" PDF_LAYOUT_MODEL_PATH = os.getenv( "UNSTRUCTUREDIO_LAYOUT_MODEL_PATH", @@ -49,6 +87,33 @@ "UNSTRUCTUREDIO_TABLE_MODEL_PATH", "/models/unstructuredio/table-transformer-structure-recognition", ) +ADAPTERS_DIR = OPERATOR_DIR / "adapters" +DEFAULT_YOLOX_MODEL_PATH = os.getenv( + "UNSTRUCTUREDIO_YOLOX_MODEL_PATH", + "/models/unstructuredio/yolox_l.pt", +) +DEFAULT_OCR_MODEL_ROOT = os.getenv( + "UNSTRUCTUREDIO_OCR_MODEL_ROOT", + "/models/unstructuredio/paddleocr", +) +DEFAULT_OCR_DET_MODEL_DIR = os.getenv( + "UNSTRUCTUREDIO_OCR_DET_MODEL_DIR", + f"{DEFAULT_OCR_MODEL_ROOT}/ch_PP-OCRv4_det_infer", +) +DEFAULT_OCR_REC_MODEL_DIR = os.getenv( + "UNSTRUCTUREDIO_OCR_REC_MODEL_DIR", + f"{DEFAULT_OCR_MODEL_ROOT}/ch_PP-OCRv4_rec_infer", +) +DEFAULT_OCR_CLS_MODEL_DIR = os.getenv( + "UNSTRUCTUREDIO_OCR_CLS_MODEL_DIR", + f"{DEFAULT_OCR_MODEL_ROOT}/ch_ppocr_mobile_v2.0_cls_infer", +) +DEFAULT_YOLOX_SRC_PATHS = [ + os.getenv("UNSTRUCTUREDIO_YOLOX_SRC_PATH", ""), + str(ADAPTERS_DIR / "YOLOX-main"), + str(OPERATOR_DIR / "YOLOX-main"), + "/models/unstructuredio/YOLOX-main", +] IMAGE_PARTITION_EXTENSIONS = {"png", "jpg", "jpeg", "tif", "tiff", "bmp"} DOCX_COORDINATE_WIDTH = 1224 DOCX_COORDINATE_HEIGHT = 1584 @@ -69,6 +134,29 @@ 9: "Text", 10: "Title", } +_NPU_OCR_ADAPTER_STATUS = { + "attempted": False, + "npu": False, + "ocr": False, + "error": None, +} +ASCEND_NPU_LIBRARY_PATHS = [ + "/usr/local/Ascend/nnal/asdsip/8.5.1/lib", + "/usr/local/Ascend/nnal/atb/8.5.1/atb/cxx_abi_0/lib", + "/usr/local/Ascend/nnal/atb/latest/atb/cxx_abi_1/lib", + "/usr/local/Ascend/nnal/asdsip/latest/lib", + "/usr/local/Ascend/cann-8.5.1/lib64", + "/usr/local/Ascend/cann-8.5.1/aarch64-linux/lib64", + "/usr/local/Ascend/cann-8.5.1/aarch64-linux/devlib", + "/usr/local/Ascend/cann-8.5.0/lib64", + "/usr/local/Ascend/cann-8.5.0/aarch64-linux/lib64", + "/usr/local/Ascend/cann-8.5.0/aarch64-linux/devlib", + "/usr/local/Ascend/ascend-toolkit/latest/lib64", + "/usr/local/Ascend/ascend-toolkit/latest/aarch64-linux/lib64", + "/usr/local/Ascend/driver/lib64", + "/usr/local/Ascend/driver/lib64/driver", + "/usr/local/Ascend/driver/lib64/common", +] def _as_bool(value: Any, default: bool) -> bool: @@ -99,6 +187,246 @@ def _as_language_list(value: Any, default: list[str]) -> list[str]: return list(default) +def _cpu_ocr_fallback_enabled() -> bool: + return _as_bool(os.getenv("UNSTRUCTUREDIO_ENABLE_CPU_OCR_FALLBACK"), False) + + +def _prepend_existing_sys_path(path: str | Path | None) -> None: + if not path: + return + resolved = Path(path) + if not resolved.exists(): + return + path_text = str(resolved) + if path_text not in sys.path: + sys.path.insert(0, path_text) + + +def _configure_npu_ocr_environment() -> None: + _prepend_existing_sys_path(ADAPTERS_DIR) + for candidate in DEFAULT_YOLOX_SRC_PATHS: + _prepend_existing_sys_path(candidate) + + os.environ.setdefault("CUSTOM_DEVICE_ROOT", "/tmp/block_paddle_npu_in_main_process") + os.environ.setdefault("TRANSFORMERS_OFFLINE", "1") + os.environ.setdefault("HF_DATASETS_OFFLINE", "1") + os.environ.setdefault("HF_HUB_OFFLINE", "1") + os.environ.setdefault("NPU_ADAPTER_YOLOX_MODEL_PATH", DEFAULT_YOLOX_MODEL_PATH) + if _cpu_ocr_fallback_enabled(): + os.environ.setdefault("OCR_ADAPTER_DEVICE", os.getenv("UNSTRUCTUREDIO_OCR_DEVICE", "npu")) + else: + os.environ["OCR_ADAPTER_DEVICE"] = "npu" + os.environ.setdefault("OCR_ADAPTER_DISABLE_NATIVE_FALLBACK", "1") + os.environ["OCR_ADAPTER_INIT_TIMEOUT"] = os.getenv("UNSTRUCTUREDIO_OCR_NPU_PROBE_TIMEOUT", "20") + os.environ.setdefault("OCR_ADAPTER_INIT_TIMEOUT", "300") + os.environ.setdefault("OCR_ADAPTER_REQUEST_TIMEOUT", "180") + os.environ.setdefault("OCR_ADAPTER_LANG", "ch") + os.environ.setdefault("OCR_ADAPTER_MODEL_ROOT", DEFAULT_OCR_MODEL_ROOT) + _configure_ascend_runtime_environment() + if _as_bool(os.getenv("UNSTRUCTUREDIO_REQUIRE_NPU_MODELS"), False): + os.environ.setdefault("OCR_ADAPTER_DISABLE_NATIVE_FALLBACK", "1") + if Path(DEFAULT_OCR_DET_MODEL_DIR).exists(): + os.environ.setdefault("OCR_ADAPTER_TEXT_DET_MODEL_DIR", DEFAULT_OCR_DET_MODEL_DIR) + if Path(DEFAULT_OCR_REC_MODEL_DIR).exists(): + os.environ.setdefault("OCR_ADAPTER_TEXT_REC_MODEL_DIR", DEFAULT_OCR_REC_MODEL_DIR) + if Path(DEFAULT_OCR_CLS_MODEL_DIR).exists(): + os.environ.setdefault("OCR_ADAPTER_TEXT_CLS_MODEL_DIR", DEFAULT_OCR_CLS_MODEL_DIR) + + +def _prepend_ld_library_paths(paths: list[str]) -> None: + existing = [part for part in os.environ.get("LD_LIBRARY_PATH", "").split(":") if part] + merged: list[str] = [] + for path in paths + existing: + if path and os.path.exists(path) and path not in merged: + merged.append(path) + if merged: + os.environ["LD_LIBRARY_PATH"] = ":".join(merged) + + +def _configure_ascend_runtime_environment() -> None: + os.environ.setdefault("FLAGS_npu_jit_compile", "0") + _prepend_ld_library_paths(ASCEND_NPU_LIBRARY_PATHS) + + +def _apply_npu_ocr_adapters() -> bool: + if _NPU_OCR_ADAPTER_STATUS["attempted"]: + return bool(_NPU_OCR_ADAPTER_STATUS["npu"] and _NPU_OCR_ADAPTER_STATUS["ocr"]) + + _NPU_OCR_ADAPTER_STATUS["attempted"] = True + _configure_npu_ocr_environment() + + errors: list[str] = [] + try: + import ocr_npu_adapter # type: ignore + + ocr_npu_adapter.apply_ocr_patch() + if _should_prewarm_cpu_ocr_runtime() and hasattr(ocr_npu_adapter, "prewarm_ocr_runtime"): + status = ocr_npu_adapter.prewarm_ocr_runtime() + if not _is_cpu_paddle_ocr_runtime(status): + raise RuntimeError(f"CPU PaddleOCR runtime is unavailable: {status}") + if _as_bool(os.getenv("UNSTRUCTUREDIO_REQUIRE_NPU_MODELS"), False): + status = ocr_npu_adapter.get_ocr_runtime_status() + if not _is_strict_npu_ocr_runtime(status): + raise RuntimeError(f"OCR NPU runtime is unavailable: {status}") + _NPU_OCR_ADAPTER_STATUS["ocr"] = True + except Exception as exc: + errors.append(f"ocr_npu_adapter: {exc}") + logger.warning("OCR adapter unavailable, will use fallback OCR path: %s", exc) + + try: + import npu_adapter # type: ignore + + npu_adapter.apply_patches() + _NPU_OCR_ADAPTER_STATUS["npu"] = True + except Exception as exc: + errors.append(f"npu_adapter: {exc}") + logger.warning("NPU adapter unavailable, will use fallback path: %s", exc) + + _NPU_OCR_ADAPTER_STATUS["error"] = "; ".join(errors) if errors else None + return bool(_NPU_OCR_ADAPTER_STATUS["npu"] and _NPU_OCR_ADAPTER_STATUS["ocr"]) + + +def _should_prewarm_cpu_ocr_runtime() -> bool: + if not _cpu_ocr_fallback_enabled(): + return False + requested_device = ( + os.getenv("UNSTRUCTUREDIO_OCR_DEVICE") + or os.getenv("OCR_ADAPTER_DEVICE") + or "" + ).strip().lower() + return requested_device == "cpu" and _as_bool(os.getenv("OCR_ADAPTER_FORCE_PADDLE_CPU"), False) + + +def _get_partition_pdf(): + global partition_pdf + if partition_pdf is not None: + return partition_pdf + try: + from unstructured.partition.pdf import partition_pdf as loaded_partition_pdf + except ImportError: + return None + partition_pdf = loaded_partition_pdf + return partition_pdf + + +def _get_ocr_runtime_status() -> dict[str, Any]: + try: + import ocr_npu_adapter # type: ignore + + if hasattr(ocr_npu_adapter, "get_ocr_runtime_status"): + status = ocr_npu_adapter.get_ocr_runtime_status() + if isinstance(status, dict): + return status + except Exception as exc: + return {"available": False, "error": str(exc)} + return {"available": False, "error": "ocr runtime status is unavailable"} + + +def _is_strict_npu_ocr_runtime(status: dict[str, Any]) -> bool: + return ( + str(status.get("device") or "").lower() == "npu" + and bool(status.get("available")) + and bool(status.get("is_alive")) + and not bool(status.get("native_only")) + ) + + +def _can_run_npu_ocr(status: dict[str, Any]) -> bool: + return _is_strict_npu_ocr_runtime(status) + + +def _is_cpu_paddle_ocr_runtime(status: dict[str, Any]) -> bool: + return ( + str(status.get("device") or "").lower() == "cpu" + and bool(status.get("available")) + and bool(status.get("is_alive")) + and not bool(status.get("native_only")) + ) + + +def _npu_ocr_mode_name() -> str: + if _NPU_OCR_ADAPTER_STATUS["npu"] and _NPU_OCR_ADAPTER_STATUS["ocr"]: + status = _get_ocr_runtime_status() + if _can_run_npu_ocr(status): + return "pdf-npu-ocr-hi_res" + return "pdf-npu-hi_res" + if _NPU_OCR_ADAPTER_STATUS["npu"]: + return "pdf-npu-hi_res" + if _NPU_OCR_ADAPTER_STATUS["ocr"]: + return "pdf-ocr-adapter-hi_res" + return "pdf-hi_res" + + +def _can_infer_pdf_table_structure(requested: bool) -> bool: + if not requested: + return False + return Path(PDF_TABLE_MODEL_PATH).exists() + + +def _has_cpu_ocr_runtime() -> bool: + return bool( + importlib.util.find_spec("unstructured_pytesseract") + or importlib.util.find_spec("pytesseract") + ) + + +def _select_table_transformer_device() -> str: + requested = os.getenv("UNSTRUCTUREDIO_TABLE_DEVICE") + if requested: + return requested + _configure_ascend_runtime_environment() + try: + import torch + import torch_npu # noqa: F401 + + if torch.npu.is_available(): + return "npu:0" + except Exception as exc: + logger.warning("Table transformer NPU unavailable, falling back to CPU: %s", exc) + return "cpu" + + +def _load_local_table_transformer_model(model_path: str | Path, device: str): + model_dir = Path(model_path) + from transformers import ( + DetrImageProcessor, + TableTransformerConfig, + TableTransformerForObjectDetection, + ) + + feature_extractor = DetrImageProcessor.from_pretrained(model_dir, local_files_only=True) + config = TableTransformerConfig.from_pretrained(model_dir, local_files_only=True) + config.use_pretrained_backbone = False + model = TableTransformerForObjectDetection(config) + + safetensors_path = model_dir / "model.safetensors" + pytorch_path = model_dir / "pytorch_model.bin" + if safetensors_path.exists(): + from safetensors.torch import load_file as load_safetensors + + state_dict = load_safetensors(str(safetensors_path), device="cpu") + elif pytorch_path.exists(): + import torch + + state_dict = torch.load(pytorch_path, map_location="cpu") + else: + raise FileNotFoundError( + f"Missing table transformer weights under {model_dir}: " + "expected model.safetensors or pytorch_model.bin" + ) + + missing, unexpected = model.load_state_dict(state_dict, strict=False) + if missing or unexpected: + logger.warning( + "Loaded table transformer with missing keys=%s unexpected keys=%s", + len(missing), + len(unexpected), + ) + model.eval() + model = model.to(device) + return feature_extractor, model + + def _render_txt(elements: Iterable[Dict[str, Any]]) -> str: sections = [] for item in elements: @@ -144,32 +472,44 @@ def _pdf_runtime_overrides(): if default_table_model is not None: tables_module.DEFAULT_MODEL = PDF_TABLE_MODEL_PATH if callable(original_load_agent): - from transformers import DetrImageProcessor, TableTransformerForObjectDetection - - def _initialize_table_model_local(self, model=None, device="cpu"): - self.device = device - self.feature_extractor = DetrImageProcessor.from_pretrained( - PDF_TABLE_MODEL_PATH, - local_files_only=True, - ) - self.model = TableTransformerForObjectDetection.from_pretrained( - PDF_TABLE_MODEL_PATH, - local_files_only=True, - use_pretrained_backbone=False, + def _initialize_table_model_local(self, model=None, device=None): + selected_device = device or _select_table_transformer_device() + self.device = selected_device + self.feature_extractor, self.model = _load_local_table_transformer_model( + model or PDF_TABLE_MODEL_PATH, + selected_device, ) - self.model.eval() - self.model = self.model.to(device) + + def _initialize_table_model_with_fallback(self, model=None, device=None): + selected_device = device or _select_table_transformer_device() + strict_npu = _as_bool(os.getenv("UNSTRUCTUREDIO_REQUIRE_NPU_MODELS"), False) + if strict_npu and selected_device == "cpu": + raise RuntimeError("Table transformer NPU is required but unavailable") + try: + _initialize_table_model_local(self, model=model, device=selected_device) + except Exception: + if strict_npu: + raise + if selected_device == "cpu": + raise + logger.warning( + "Unable to initialize table transformer on NPU, falling back to CPU", + exc_info=True, + ) + _initialize_table_model_local(self, model=model, device="cpu") def _load_agent_with_local_model(): if getattr(tables_module.tables_agent, "model", None) is None: - _initialize_table_model_local( + _initialize_table_model_with_fallback( tables_module.tables_agent, PDF_TABLE_MODEL_PATH, - device="cpu", + device=_select_table_transformer_device(), ) if original_initialize is not None: - tables_module.UnstructuredTableTransformerModel.initialize = _initialize_table_model_local + tables_module.UnstructuredTableTransformerModel.initialize = ( + _initialize_table_model_with_fallback + ) tables_module.load_agent = _load_agent_with_local_model except Exception as exc: logger.warning("Unable to override unstructured table model path: %s", exc) @@ -196,10 +536,16 @@ def _load_agent_with_local_model(): def _element_to_dict(index: int, element: Any) -> Dict[str, Any]: metadata = getattr(element, "metadata", None) coordinates = getattr(metadata, "coordinates", None) if metadata else None + text = getattr(element, "text", None) + if text is None: + with contextlib.suppress(Exception): + text = str(element) + if text is None: + text = "" return { "index": index, "category": getattr(element, "category", element.__class__.__name__), - "text": str(getattr(element, "text", str(element))), + "text": str(text), "page_number": getattr(metadata, "page_number", None) if metadata else None, "coordinates": str(coordinates) if coordinates is not None else None, "text_as_html": getattr(metadata, "text_as_html", None) if metadata else None, @@ -256,6 +602,86 @@ def _filter_obvious_pdf_noise(items: list[Dict[str, Any]]) -> list[Dict[str, Any return filtered +_PDF_TABLE_CAPTION_RE = re.compile(r"^\s*Table\s+\d+\s*:", re.IGNORECASE) + + +def _looks_like_table_caption(text: str) -> bool: + return bool(_PDF_TABLE_CAPTION_RE.match(text or "")) + + +def _looks_like_table_body(text: str) -> bool: + normalized = " ".join((text or "").split()) + if len(normalized) < 30: + return False + citation_stripped = re.sub(r"\[\s*\d+(?:\s*,\s*\d+)*\s*\]", " ", normalized) + numeric_tokens = re.findall(r"(?= 0.45 + + +def _table_text_to_html(text: str) -> str: + rows = [] + for line in (text or "").splitlines(): + cells = [cell for cell in re.split(r"\s{2,}|\t+", line.strip()) if cell] + if not cells and line.strip(): + cells = [line.strip()] + if cells: + rows.append(cells) + if not rows: + rows = [[(text or "").strip()]] + rendered_rows = [] + for row_index, row in enumerate(rows): + tag = "th" if row_index == 0 else "td" + rendered_rows.append("" + "".join(f"<{tag}>{html.escape(cell)}" for cell in row) + "") + return "\n" + "\n".join(rendered_rows) + "\n
    " + + +def _promote_obvious_pdf_tables(items: list[Dict[str, Any]]) -> list[Dict[str, Any]]: + promoted = [] + for item in items: + text = str(item.get("text") or "").strip() + if item.get("category") == "Table" and text and not item.get("text_as_html"): + item = dict(item) + item["text_as_html"] = _table_text_to_html(text) + elif item.get("category") != "Table" and ( + _looks_like_table_caption(text) or _looks_like_table_body(text) + ): + item = dict(item) + item["category"] = "Table" + if not item.get("text_as_html"): + item["text_as_html"] = _table_text_to_html(text) + promoted.append(item) + return promoted + + +def _has_table_reference(items: list[Dict[str, Any]]) -> bool: + return any(_looks_like_table_caption(str(item.get("text") or "").strip()) for item in items) + + +def _merge_pdf_table_supplements( + base_items: list[Dict[str, Any]], + supplement_items: list[Dict[str, Any]], +) -> list[Dict[str, Any]]: + if any(item.get("category") == "Table" for item in base_items): + return base_items + existing_texts = {" ".join(str(item.get("text") or "").split()).lower() for item in base_items} + merged = list(base_items) + for item in supplement_items: + if item.get("category") != "Table": + continue + normalized = " ".join(str(item.get("text") or "").split()).lower() + if not normalized or normalized in existing_texts: + continue + table_item = dict(item) + table_item["index"] = len(merged) + merged.append(table_item) + existing_texts.add(normalized) + return merged + + def _normalize_paragraph_text(text: str) -> str: return " ".join(text.split()).strip() @@ -467,6 +893,39 @@ def _extract_docx_fastpath(file_path: Path) -> list[Dict[str, Any]]: return elements +def _convert_office_to_pdf(file_path: Path) -> Path: + soffice = ( + os.getenv("UNSTRUCTUREDIO_LIBREOFFICE_BIN") + or shutil.which("libreoffice") + or shutil.which("soffice") + ) + if not soffice: + raise RuntimeError("LibreOffice/soffice is required for DOCX/DOC visual NPU extraction") + + output_dir = Path(tempfile.mkdtemp(prefix="unstructuredio_office_pdf_")) + cmd = [ + soffice, + "--headless", + "--convert-to", + "pdf", + "--outdir", + str(output_dir), + str(file_path), + ] + completed = subprocess.run(cmd, capture_output=True, text=True, timeout=120, check=False) + if completed.returncode != 0: + message = (completed.stderr or completed.stdout or "").strip() + raise RuntimeError(f"Office to PDF conversion failed: {message}") + + converted = output_dir / f"{file_path.stem}.pdf" + if not converted.exists(): + candidates = sorted(output_dir.glob("*.pdf")) + if not candidates: + raise RuntimeError("Office to PDF conversion did not produce a PDF") + converted = candidates[0] + return converted + + class UnstructuredIOMapper(Mapper): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -476,6 +935,13 @@ def __init__(self, *args, **kwargs): self.enable_docx_fastpath = _as_bool(kwargs.get("enableDocxFastpath", True), True) self.suppress_pdf_noise = _as_bool(kwargs.get("suppressPdfNoise", True), True) self.fallback_to_auto = _as_bool(kwargs.get("fallbackToAuto", True), True) + self.require_npu_models = _as_bool( + kwargs.get("requireNpuModels"), + _as_bool(os.getenv("UNSTRUCTUREDIO_REQUIRE_NPU_MODELS"), False), + ) + if self.require_npu_models: + os.environ.setdefault("UNSTRUCTUREDIO_REQUIRE_NPU_MODELS", "1") + os.environ.setdefault("OCR_ADAPTER_DISABLE_NATIVE_FALLBACK", "1") self.json_indent = max(0, _as_int(kwargs.get("jsonIndent", 2), 2)) self.pdf_languages = _as_language_list(kwargs.get("pdfLanguages"), ["chi_sim", "eng"]) @@ -495,6 +961,13 @@ def execute(self, sample: Dict[str, Any]) -> Dict[str, Any]: return sample def _extract_elements(self, file_path: Path, file_type: str) -> tuple[list[Dict[str, Any]], str]: + if file_type in {"docx", "doc"} and self.require_npu_models: + converted_pdf = _convert_office_to_pdf(file_path) + elements, mode = self._extract_pdf(converted_pdf) + if mode != "pdf-npu-ocr-hi_res": + raise RuntimeError(f"DOCX visual NPU route did not use NPU OCR mode: {mode}") + return elements, f"{file_type}-visual-{mode}" + if file_type == "docx" and self.enable_docx_fastpath: try: elements = _extract_docx_fastpath(file_path) @@ -520,30 +993,132 @@ def _extract_pdf(self, file_path: Path) -> tuple[list[Dict[str, Any]], str]: pdf_kwargs = { "filename": str(file_path), "strategy": self.pdf_strategy, - "infer_table_structure": self.pdf_infer_table_structure, + "infer_table_structure": _can_infer_pdf_table_structure(self.pdf_infer_table_structure), "languages": self.pdf_languages, } auto_kwargs = { "filename": str(file_path), "languages": self.pdf_languages, } - if partition_pdf is None: + npu_kwargs = dict(pdf_kwargs) + npu_kwargs.update( + { + "strategy": "hi_res", + "hi_res_model_name": "yolox", + "pdf_image_dpi": 150, + } + ) + try: + adapters_ready = _apply_npu_ocr_adapters() + npu_layout_ready = adapters_ready or bool(_NPU_OCR_ADAPTER_STATUS["npu"]) + if not npu_layout_ready: + raise RuntimeError("NPU layout adapter is unavailable") + ocr_runtime_status = _get_ocr_runtime_status() + npu_ocr_ready = _can_run_npu_ocr(ocr_runtime_status) + if not npu_ocr_ready: + if self.require_npu_models: + raise RuntimeError("OCR NPU runtime is unavailable; refusing CPU OCR fallback") + logger.warning( + "OCR NPU runtime unavailable for %s; using fast PDF fallback instead of CPU OCR", + file_path.name, + ) + raise RuntimeError("OCR NPU runtime is unavailable") + npu_kwargs.update({"ocr_strategy": "force", "ocr_mode": "entire_page"}) + pdf_partition = _get_partition_pdf() + if pdf_partition is None: + raise RuntimeError("partition_pdf is required for NPU PDF extraction") + with _pdf_runtime_overrides(): + npu_elements = _serialize_elements(pdf_partition(**npu_kwargs)) + if not self._needs_pdf_fallback(npu_elements): + npu_elements = _promote_obvious_pdf_tables(npu_elements) + npu_elements = self._supplement_pdf_tables_if_missing(file_path, npu_elements) + return npu_elements, _npu_ocr_mode_name() + logger.warning("NPU/OCR PDF path produced weak output for %s; falling back", file_path.name) + except Exception as exc: + if self.require_npu_models: + raise + logger.warning("NPU/OCR PDF path failed for %s; falling back: %s", file_path.name, exc) + + pdf_partition = _get_partition_pdf() + if pdf_partition is None: return _serialize_elements(partition_auto(**auto_kwargs)), "partition-auto" - with _pdf_runtime_overrides(): - elements = partition_pdf(**pdf_kwargs) - serialized = _serialize_elements(elements) - if self.pdf_strategy == "fast" and self.fallback_to_auto and self._needs_pdf_fallback(serialized): + fallback_strategy = "fast" if self.fallback_to_auto else self.pdf_strategy + if self.pdf_strategy == "hi_res" and not self.fallback_to_auto: + fallback_strategy = "auto" + pdf_kwargs["strategy"] = fallback_strategy + try: + with _pdf_runtime_overrides(): + elements = pdf_partition(**pdf_kwargs) + serialized = _serialize_elements(elements) + serialized = _promote_obvious_pdf_tables(serialized) + except Exception as exc: + logger.warning( + "PDF fallback strategy %s failed for %s: %s", + fallback_strategy, + file_path.name, + exc, + ) + if fallback_strategy != "auto": + fallback_kwargs = dict(pdf_kwargs) + fallback_kwargs["strategy"] = "auto" + with _pdf_runtime_overrides(): + return ( + _promote_obvious_pdf_tables(_serialize_elements(pdf_partition(**fallback_kwargs))), + "pdf-npu-ocr-fallback-auto", + ) + raise + if fallback_strategy == "fast" and self.fallback_to_auto and self._needs_pdf_fallback(serialized): fallback_kwargs = dict(pdf_kwargs) fallback_kwargs["strategy"] = "auto" + try: + with _pdf_runtime_overrides(): + return ( + _promote_obvious_pdf_tables(_serialize_elements(pdf_partition(**fallback_kwargs))), + "pdf-npu-ocr-fallback-auto", + ) + except Exception as exc: + logger.warning( + "PDF auto fallback failed for %s; keeping fast result: %s", + file_path.name, + exc, + ) + return serialized, f"pdf-npu-ocr-fallback-{fallback_strategy}" + + def _supplement_pdf_tables_if_missing( + self, + file_path: Path, + elements: list[Dict[str, Any]], + ) -> list[Dict[str, Any]]: + if any(item.get("category") == "Table" for item in elements): + return elements + pdf_partition = _get_partition_pdf() + if pdf_partition is None: + return elements + try: with _pdf_runtime_overrides(): - return _serialize_elements(partition_pdf(**fallback_kwargs)), "pdf-fast-fallback-auto" - return serialized, f"pdf-{self.pdf_strategy}" + supplement = _serialize_elements( + pdf_partition( + filename=str(file_path), + strategy="fast", + infer_table_structure=False, + languages=self.pdf_languages, + ) + ) + except Exception as exc: + logger.warning("PDF table supplement failed for %s: %s", file_path.name, exc) + return elements + return _merge_pdf_table_supplements(elements, _promote_obvious_pdf_tables(supplement)) @staticmethod def _needs_pdf_fallback(elements: list[Dict[str, Any]]) -> bool: - text_chars = sum(len(str(item.get("text") or "")) for item in elements) - return len(elements) < 3 or text_chars < 80 + texts = [str(item.get("text") or "") for item in elements] + text_chars = sum(len(text) for text in texts) + informative_chars = sum(ch.isalnum() or "\u4e00" <= ch <= "\u9fff" for text in texts for ch in text) + if len(elements) < 3 or text_chars < 80 or informative_chars < 20: + return True + has_structured_table = any(item.get("category") == "Table" for item in elements) + return _has_table_reference(elements) and not has_structured_table def _render_output(self, payload: Dict[str, Any]) -> str: if self.export_type == "txt": diff --git a/runtime/ops/mapper/unstructuredio/operator_src/run_strict_pdf_docx_smoke.py b/runtime/ops/mapper/unstructuredio/operator_src/run_strict_pdf_docx_smoke.py new file mode 100644 index 00000000..bf2226af --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/run_strict_pdf_docx_smoke.py @@ -0,0 +1,78 @@ +from __future__ import annotations + +import json +import os +import sys +import time +import types +from pathlib import Path + + +def _install_datamate_stub() -> None: + if "datamate.core.base_op" in sys.modules: + return + datamate = types.ModuleType("datamate") + core = types.ModuleType("datamate.core") + base_op = types.ModuleType("datamate.core.base_op") + + class Mapper: + def __init__(self, *args, **kwargs): + self.filepath_key = "filepath" + self.filetype_key = "filetype" + self.text_key = "text" + self.target_type_key = "target_type" + + class Operators: + def register_module(self, *args, **kwargs): + return None + + base_op.Mapper = Mapper + base_op.OPERATORS = Operators() + core.base_op = base_op + datamate.core = core + sys.modules["datamate"] = datamate + sys.modules["datamate.core"] = core + sys.modules["datamate.core.base_op"] = base_op + + +def _run_one(process, file_path: Path) -> dict[str, object]: + mapper = process.UnstructuredIOMapper(requireNpuModels=True, pdfStrategy="auto") + file_type = file_path.suffix.lstrip(".").lower() + started = time.perf_counter() + elements, mode = mapper._extract_elements(file_path, file_type) + duration = round(time.perf_counter() - started, 2) + payload = mapper._build_payload(file_path, elements, mode, duration) + out_path = file_path.with_name(f"{file_path.stem}_strict_npu_result.json") + out_path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8") + return { + "input": str(file_path), + "output": str(out_path), + "mode": mode, + "duration_seconds": duration, + "element_count": len(elements), + "table_count": payload["table_count"], + } + + +def main(argv: list[str]) -> int: + if len(argv) < 2: + print("Usage: python run_strict_pdf_docx_smoke.py [more-files...]", file=sys.stderr) + return 2 + + os.environ.setdefault("UNSTRUCTUREDIO_REQUIRE_NPU_MODELS", "1") + os.environ.setdefault("OCR_ADAPTER_DISABLE_NATIVE_FALLBACK", "1") + os.environ.setdefault("OCR_ADAPTER_DEVICE", "npu") + + _install_datamate_stub() + import process + + results = [] + for item in argv[1:]: + results.append(_run_one(process, Path(item).resolve())) + + print(json.dumps(results, ensure_ascii=False, indent=2)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main(sys.argv)) diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_check_npu_runtime.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_check_npu_runtime.py new file mode 100644 index 00000000..0f347920 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_check_npu_runtime.py @@ -0,0 +1,65 @@ +import importlib.util +import subprocess +from pathlib import Path + + +def _load_check_module(): + module_path = Path(__file__).resolve().parents[1] / "check_npu_runtime.py" + spec = importlib.util.spec_from_file_location("check_npu_runtime_under_test", module_path) + module = importlib.util.module_from_spec(spec) + assert spec is not None and spec.loader is not None + spec.loader.exec_module(module) + return module + + +def test_module_probe_runs_each_import_in_isolated_process(monkeypatch): + check = _load_check_module() + commands = [] + + def fake_run(command, **kwargs): + commands.append(command) + return subprocess.CompletedProcess(command, 0, stdout='{"available": true, "version": "x"}\n', stderr="") + + monkeypatch.setattr(check.subprocess, "run", fake_run) + + assert check._module_version("torch_npu") == {"available": True, "version": "x"} + assert commands[0][0] == check.sys.executable + assert "importlib.import_module('torch_npu')" in commands[0][2] + + +def test_main_accepts_split_torch_and_paddle_npu_probe_success(monkeypatch, tmp_path, capsys): + check = _load_check_module() + model_dir = tmp_path / "model" + model_dir.mkdir() + + monkeypatch.setattr(check, "_module_version", lambda name: {"available": True, "version": name}) + monkeypatch.setenv("UNSTRUCTUREDIO_YOLOX_MODEL_PATH", str(model_dir)) + monkeypatch.setenv("UNSTRUCTUREDIO_YOLOX_SRC_PATH", str(model_dir)) + monkeypatch.setenv("UNSTRUCTUREDIO_OCR_DET_MODEL_DIR", str(model_dir)) + monkeypatch.setenv("UNSTRUCTUREDIO_OCR_REC_MODEL_DIR", str(model_dir)) + monkeypatch.setenv("UNSTRUCTUREDIO_OCR_CLS_MODEL_DIR", str(model_dir)) + + assert check.main() == 0 + report = capsys.readouterr().out + assert '"torch_npu"' in report + assert '"paddleocr"' in report + + +def test_module_probe_injects_ascend_library_paths(monkeypatch): + check = _load_check_module() + seen_envs = [] + + def fake_exists(path): + return path in {"/opt/ascend/lib", "/tmp/existing"} + + def fake_run(command, **kwargs): + seen_envs.append(kwargs["env"]) + return subprocess.CompletedProcess(command, 0, stdout='{"available": true, "version": "x"}\n', stderr="") + + monkeypatch.setattr(check.os.path, "exists", fake_exists) + monkeypatch.setattr(check, "ASCEND_NPU_LIBRARY_PATHS", ("/opt/ascend/lib", "/missing")) + monkeypatch.setenv("LD_LIBRARY_PATH", "/tmp/existing") + monkeypatch.setattr(check.subprocess, "run", fake_run) + + assert check._module_version("paddle")["available"] is True + assert seen_envs[0]["LD_LIBRARY_PATH"].split(":") == ["/opt/ascend/lib", "/tmp/existing"] diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_npu_adapter_cpu_fallback.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_npu_adapter_cpu_fallback.py new file mode 100644 index 00000000..12ea3453 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_npu_adapter_cpu_fallback.py @@ -0,0 +1,31 @@ +import importlib.util +import sys +import types +from pathlib import Path + + +def _load_npu_adapter(): + if "torch_npu" not in sys.modules: + sys.modules["torch_npu"] = types.ModuleType("torch_npu") + module_path = Path(__file__).resolve().parents[1] / "adapters" / "npu_adapter.py" + spec = importlib.util.spec_from_file_location("npu_adapter_under_test", module_path) + module = importlib.util.module_from_spec(spec) + assert spec is not None and spec.loader is not None + spec.loader.exec_module(module) + return module + + +def test_npu_get_model_delegates_to_original_loader_when_cpu_forced_and_local_model_missing(monkeypatch): + adapter = _load_npu_adapter() + calls = [] + + def original_get_model(model_name, **kwargs): + calls.append((model_name, kwargs)) + return "cpu-model" + + adapter._ORIGINAL_GET_MODEL = original_get_model + monkeypatch.setattr(adapter, "_resolve_yolox_model_path", lambda: str(Path("missing.pt"))) + monkeypatch.setenv("UNSTRUCTUREDIO_FORCE_CPU_MODELS", "1") + + assert adapter.npu_get_model("yolox", foo="bar", password="secret") == "cpu-model" + assert calls == [("yolox", {"foo": "bar"})] diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_ocr_cpu_patch.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_ocr_cpu_patch.py new file mode 100644 index 00000000..8362d754 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_ocr_cpu_patch.py @@ -0,0 +1,45 @@ +import importlib.util +from pathlib import Path + + +def _load_ocr_adapter(): + module_path = Path(__file__).resolve().parents[1] / "adapters" / "ocr_npu_adapter.py" + spec = importlib.util.spec_from_file_location("ocr_adapter_under_test", module_path) + module = importlib.util.module_from_spec(spec) + assert spec is not None and spec.loader is not None + spec.loader.exec_module(module) + return module + + +def test_force_paddle_cpu_patch_does_not_require_native_tesseract(monkeypatch): + adapter = _load_ocr_adapter() + + def fail_native_load(): + raise ModuleNotFoundError("pytesseract") + + monkeypatch.setattr(adapter, "_load_native_tesseract_modules", fail_native_load) + monkeypatch.setenv("OCR_ADAPTER_FORCE_PADDLE_CPU", "1") + + adapter.apply_ocr_patch() + + assert "pytesseract" in adapter.sys.modules + assert "unstructured_pytesseract" in adapter.sys.modules + + +def test_cpu_paddle_availability_check_does_not_import_paddle_in_parent(monkeypatch): + adapter = _load_ocr_adapter() + imported = [] + + def fake_find_spec(name): + return object() if name in {"paddle", "paddleocr"} else None + + def fail_import(name): + imported.append(name) + raise AssertionError("parent process must not import paddle for CPU OCR availability") + + monkeypatch.setattr(adapter.importlib.util, "find_spec", fake_find_spec) + monkeypatch.setattr(adapter.importlib, "import_module", fail_import) + monkeypatch.setenv("OCR_ADAPTER_DEVICE", "cpu") + + assert adapter._paddle_ocr_available() is True + assert imported == [] diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_pdf_npu_ocr_priority.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_pdf_npu_ocr_priority.py new file mode 100644 index 00000000..60584957 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_pdf_npu_ocr_priority.py @@ -0,0 +1,390 @@ +import importlib.util +import os +import sys +import types +from pathlib import Path + + +def _load_process_module(): + datamate = types.ModuleType("datamate") + core = types.ModuleType("datamate.core") + base_op = types.ModuleType("datamate.core.base_op") + + class _Mapper: + def __init__(self, *args, **kwargs): + self.filepath_key = "filepath" + self.filetype_key = "filetype" + self.text_key = "text" + self.target_type_key = "target_type" + + base_op.Mapper = _Mapper + core.base_op = base_op + datamate.core = core + sys.modules["datamate"] = datamate + sys.modules["datamate.core"] = core + sys.modules["datamate.core.base_op"] = base_op + + if "unstructured" not in sys.modules: + unstructured = types.ModuleType("unstructured") + partition = types.ModuleType("unstructured.partition") + auto = types.ModuleType("unstructured.partition.auto") + + def _partition(*args, **kwargs): + raise NotImplementedError("partition_auto stub should not be used in these tests") + + auto.partition = _partition + partition.auto = auto + unstructured.partition = partition + sys.modules["unstructured"] = unstructured + sys.modules["unstructured.partition"] = partition + sys.modules["unstructured.partition.auto"] = auto + + module_path = Path(__file__).resolve().parents[1] / "process.py" + spec = importlib.util.spec_from_file_location("unstructuredio_process_under_test", module_path) + module = importlib.util.module_from_spec(spec) + assert spec is not None and spec.loader is not None + spec.loader.exec_module(module) + return module + + +class _Metadata: + page_number = 1 + coordinates = None + text_as_html = None + + +class _Element: + category = "NarrativeText" + metadata = _Metadata() + + def __init__(self, text): + self.text = text + + +def test_process_disables_nltk_auto_download_before_unstructured_import(monkeypatch): + monkeypatch.delenv("AUTO_DOWNLOAD_NLTK", raising=False) + + _load_process_module() + + assert os.environ["AUTO_DOWNLOAD_NLTK"] == "False" + + +def test_pdf_keeps_fast_result_when_auto_fallback_raises(monkeypatch): + process = _load_process_module() + calls = [] + + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) + monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) + monkeypatch.setattr(process, "_get_ocr_runtime_status", lambda: {"available": False, "device": "npu"}) + + def _partition_pdf(**kwargs): + calls.append(kwargs["strategy"]) + if kwargs["strategy"] == "auto": + raise RuntimeError("simulated auto fallback failure") + return [_Element("x"), _Element("y"), _Element("z")] + + monkeypatch.setattr(process, "partition_pdf", _partition_pdf) + + mapper = process.UnstructuredIOMapper(pdfStrategy="auto") + elements, mode = mapper._extract_pdf(Path("sample.pdf")) + + assert calls == ["fast", "auto"] + assert mode == "pdf-npu-ocr-fallback-fast" + assert [item["text"] for item in elements] == ["x", "y", "z"] + + +def test_pdf_skips_cpu_hi_res_model_fallback_even_when_cpu_ocr_exists(monkeypatch): + process = _load_process_module() + calls = [] + + monkeypatch.delenv("UNSTRUCTUREDIO_TABLE_DEVICE", raising=False) + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) + monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) + monkeypatch.setattr(process, "_has_cpu_ocr_runtime", lambda: True) + monkeypatch.setattr(process, "_get_ocr_runtime_status", lambda: {"available": False, "device": "npu"}) + + def _partition_pdf(**kwargs): + calls.append( + { + "strategy": kwargs["strategy"], + "hi_res_model_name": kwargs.get("hi_res_model_name"), + "table_device": process.os.environ.get("UNSTRUCTUREDIO_TABLE_DEVICE"), + } + ) + return [ + _Element("long enough text from fast fallback one with useful content"), + _Element("long enough text from fast fallback two with useful content"), + _Element("long enough text from fast fallback three with useful content"), + ] + + monkeypatch.setattr(process, "partition_pdf", _partition_pdf) + + mapper = process.UnstructuredIOMapper(pdfStrategy="auto") + elements, mode = mapper._extract_pdf(Path("sample.pdf")) + + assert calls == [{"strategy": "fast", "hi_res_model_name": None, "table_device": None}] + assert mode == "pdf-npu-ocr-fallback-fast" + assert len(elements) == 3 + + +def test_pdf_skips_cpu_hi_res_when_cpu_ocr_runtime_missing(monkeypatch): + process = _load_process_module() + calls = [] + + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) + monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) + monkeypatch.setattr(process, "_has_cpu_ocr_runtime", lambda: False) + monkeypatch.setattr(process, "_get_ocr_runtime_status", lambda: {"available": False, "device": "npu"}) + + def _partition_pdf(**kwargs): + calls.append(kwargs["strategy"]) + return [ + _Element("fast text one with enough useful extracted content"), + _Element("fast text two with enough useful extracted content"), + _Element("fast text three with enough useful extracted content"), + ] + + monkeypatch.setattr(process, "partition_pdf", _partition_pdf) + + mapper = process.UnstructuredIOMapper(pdfStrategy="auto") + elements, mode = mapper._extract_pdf(Path("sample.pdf")) + + assert calls == ["fast"] + assert mode == "pdf-npu-ocr-fallback-fast" + assert len(elements) == 3 + + +def test_pdf_runs_npu_hi_res_when_npu_ocr_is_available(monkeypatch): + process = _load_process_module() + seen_kwargs = [] + + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) + process._NPU_OCR_ADAPTER_STATUS.update({"attempted": True, "npu": True, "ocr": True, "error": None}) + monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) + monkeypatch.setattr( + process, + "_get_ocr_runtime_status", + lambda: {"available": True, "device": "npu", "native_only": False, "is_alive": True}, + ) + + def _partition_pdf(**kwargs): + seen_kwargs.append(kwargs) + return [ + _Element("long enough npu layout text one with useful extracted content"), + _Element("long enough npu layout text two with useful extracted content"), + _Element("long enough npu layout text three with useful extracted content"), + ] + + monkeypatch.setattr(process, "partition_pdf", _partition_pdf) + + mapper = process.UnstructuredIOMapper(pdfStrategy="auto") + elements, mode = mapper._extract_pdf(Path("sample.pdf")) + + assert seen_kwargs[0]["strategy"] == "hi_res" + assert seen_kwargs[0]["hi_res_model_name"] == "yolox" + assert seen_kwargs[0]["ocr_strategy"] == "force" + assert seen_kwargs[0]["ocr_mode"] == "entire_page" + assert mode == "pdf-npu-ocr-hi_res" + assert len(elements) == 3 + + +def test_pdf_uses_fast_path_when_ocr_adapter_is_unavailable(monkeypatch): + process = _load_process_module() + seen_kwargs = [] + + def apply_partial_adapters(): + process._NPU_OCR_ADAPTER_STATUS.update( + {"attempted": True, "npu": True, "ocr": False, "error": "ocr unavailable"} + ) + return False + + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", apply_partial_adapters) + monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) + monkeypatch.setattr(process, "_get_ocr_runtime_status", lambda: {"available": False}) + + def _partition_pdf(**kwargs): + seen_kwargs.append(kwargs) + return [ + _Element("long enough npu layout text one with useful extracted content"), + _Element("long enough npu layout text two with useful extracted content"), + _Element("long enough npu layout text three with useful extracted content"), + ] + + monkeypatch.setattr(process, "partition_pdf", _partition_pdf) + + mapper = process.UnstructuredIOMapper(pdfStrategy="auto") + elements, mode = mapper._extract_pdf(Path("sample.pdf")) + + assert seen_kwargs[0]["strategy"] == "fast" + assert "hi_res_model_name" not in seen_kwargs[0] + assert "ocr_strategy" not in seen_kwargs[0] + assert mode == "pdf-npu-ocr-fallback-fast" + assert len(elements) == 3 + + +def test_pdf_falls_back_when_table_caption_has_no_table(monkeypatch): + process = _load_process_module() + calls = [] + + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) + monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) + monkeypatch.setattr(process, "_has_cpu_ocr_runtime", lambda: False) + monkeypatch.setattr(process, "_get_ocr_runtime_status", lambda: {"available": True, "device": "npu", "native_only": False, "is_alive": True}) + + def _partition_pdf(**kwargs): + calls.append(kwargs["strategy"]) + if kwargs["strategy"] == "hi_res": + return [ + _Element("Attention Is All You Need"), + _Element( + "Table 3: Variations on the Transformer architecture. " + "This line says a table exists but the model did not return a Table element." + ), + _Element("long enough surrounding text with useful extracted content"), + ] + return [ + _Element("fast text one with enough useful extracted content"), + _Element("Table 3: Variations BLEU PPL params 25.8 4.92 65M 26.4 4.75 80M"), + _Element("fast text three with enough useful extracted content"), + ] + + monkeypatch.setattr(process, "partition_pdf", _partition_pdf) + + mapper = process.UnstructuredIOMapper(pdfStrategy="auto") + elements, mode = mapper._extract_pdf(Path("sample.pdf")) + + assert calls[:2] == ["hi_res", "fast"] + assert mode == "pdf-npu-ocr-fallback-fast" + assert any(item["category"] == "Table" for item in elements) + + +def test_pdf_table_body_heuristic_rejects_numeric_citation_paragraph(): + process = _load_process_module() + + text = ( + "Recurrent neural networks, long short-term memory [13] and gated recurrent [7] " + "neural networks in particular, have been firmly established as state of the art " + "approaches in sequence modeling and transduction problems such as language " + "modeling and machine translation [35, 2, 5]. Numerous efforts have since " + "continued to push the boundaries of recurrent language models and encoder-decoder " + "architectures [38, 24, 15]." + ) + + assert process._looks_like_table_body(text) is False + + +def test_pdf_table_body_heuristic_accepts_dense_numeric_table_row(): + process = _load_process_module() + + text = ( + "PPL train steps (dev) 100K 4.92 5.29 5.00 4.91 5.01 5.16 5.01 " + "6.11 5.19 4.88 5.75 4.66 5.12 4.75 5.77 4.95 4.67 5.47 4.92 300K 4.33" + ) + + assert process._looks_like_table_body(text) is True + + +def test_existing_pdf_table_gets_html_when_missing(): + process = _load_process_module() + + items = [ + { + "category": "Table", + "text": "Layer Type Complexity O(n) Self-Attention O(n².d)", + "text_as_html": None, + } + ] + + promoted = process._promote_obvious_pdf_tables(items) + + assert promoted[0]["category"] == "Table" + assert promoted[0]["text_as_html"].startswith("") + + +def test_npu_mode_name_does_not_treat_cpu_ocr_as_npu(monkeypatch): + process = _load_process_module() + process._NPU_OCR_ADAPTER_STATUS.update({"npu": True, "ocr": True}) + monkeypatch.setattr( + process, + "_get_ocr_runtime_status", + lambda: {"available": True, "device": "cpu", "native_only": False, "is_alive": True}, + ) + + assert process._npu_ocr_mode_name() == "pdf-npu-hi_res" + + +def test_apply_adapters_prewarms_cpu_ocr_before_npu_adapter(monkeypatch): + process = _load_process_module() + calls = [] + + fake_ocr = types.ModuleType("ocr_npu_adapter") + + def apply_ocr_patch(): + calls.append("ocr_patch") + + def prewarm_ocr_runtime(): + calls.append("ocr_prewarm") + return {"available": True, "device": "cpu", "native_only": False, "is_alive": True} + + def get_ocr_runtime_status(): + calls.append("ocr_status") + return {"available": True, "device": "cpu", "native_only": False, "is_alive": True} + + fake_ocr.apply_ocr_patch = apply_ocr_patch + fake_ocr.prewarm_ocr_runtime = prewarm_ocr_runtime + fake_ocr.get_ocr_runtime_status = get_ocr_runtime_status + + fake_npu = types.ModuleType("npu_adapter") + + def apply_patches(): + calls.append("npu_patch") + + fake_npu.apply_patches = apply_patches + + monkeypatch.setitem(sys.modules, "ocr_npu_adapter", fake_ocr) + monkeypatch.setitem(sys.modules, "npu_adapter", fake_npu) + monkeypatch.setenv("UNSTRUCTUREDIO_OCR_DEVICE", "cpu") + monkeypatch.setenv("OCR_ADAPTER_FORCE_PADDLE_CPU", "1") + monkeypatch.setenv("UNSTRUCTUREDIO_ENABLE_CPU_OCR_FALLBACK", "1") + + assert process._apply_npu_ocr_adapters() is True + assert calls == ["ocr_patch", "ocr_prewarm", "npu_patch"] + assert process._NPU_OCR_ADAPTER_STATUS["ocr"] is True + assert process._NPU_OCR_ADAPTER_STATUS["npu"] is True + + +def test_apply_adapters_does_not_prewarm_default_npu_ocr(monkeypatch): + process = _load_process_module() + calls = [] + + fake_ocr = types.ModuleType("ocr_npu_adapter") + fake_ocr.apply_ocr_patch = lambda: calls.append("ocr_patch") + fake_ocr.prewarm_ocr_runtime = lambda: calls.append("ocr_prewarm") + fake_ocr.get_ocr_runtime_status = lambda: {"available": False, "device": "npu"} + + fake_npu = types.ModuleType("npu_adapter") + fake_npu.apply_patches = lambda: calls.append("npu_patch") + + monkeypatch.setitem(sys.modules, "ocr_npu_adapter", fake_ocr) + monkeypatch.setitem(sys.modules, "npu_adapter", fake_npu) + monkeypatch.delenv("UNSTRUCTUREDIO_OCR_DEVICE", raising=False) + monkeypatch.delenv("OCR_ADAPTER_DEVICE", raising=False) + + assert process._apply_npu_ocr_adapters() is True + assert calls == ["ocr_patch", "npu_patch"] + + +def test_configure_npu_ocr_environment_overrides_cpu_ocr_request(monkeypatch): + process = _load_process_module() + + monkeypatch.setenv("UNSTRUCTUREDIO_OCR_DEVICE", "cpu") + monkeypatch.setenv("OCR_ADAPTER_DEVICE", "cpu") + monkeypatch.setenv("OCR_ADAPTER_FORCE_PADDLE_CPU", "1") + monkeypatch.delenv("UNSTRUCTUREDIO_ENABLE_CPU_OCR_FALLBACK", raising=False) + monkeypatch.setattr(process, "_prepend_existing_sys_path", lambda path: None) + monkeypatch.setattr(process, "_configure_ascend_runtime_environment", lambda: None) + + process._configure_npu_ocr_environment() + + assert process.os.environ["OCR_ADAPTER_DEVICE"] == "npu" + assert process.os.environ["OCR_ADAPTER_DISABLE_NATIVE_FALLBACK"] == "1" diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_process_ascend_env.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_process_ascend_env.py new file mode 100644 index 00000000..2a454a01 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_process_ascend_env.py @@ -0,0 +1,27 @@ +from test_pdf_npu_ocr_priority import _load_process_module + + +def test_process_ascend_env_includes_nnal_and_cann_variants(monkeypatch): + process = _load_process_module() + existing = "/tmp/existing_ld" + accepted = { + "/usr/local/Ascend/nnal/asdsip/8.5.1/lib", + "/usr/local/Ascend/nnal/atb/8.5.1/atb/cxx_abi_0/lib", + "/usr/local/Ascend/nnal/atb/latest/atb/cxx_abi_1/lib", + "/usr/local/Ascend/cann-8.5.0/lib64", + existing, + } + + monkeypatch.setenv("LD_LIBRARY_PATH", existing) + monkeypatch.setattr(process.os.path, "exists", lambda path: path in accepted) + + process._configure_ascend_runtime_environment() + + paths = process.os.environ["LD_LIBRARY_PATH"].split(":") + assert paths[:4] == [ + "/usr/local/Ascend/nnal/asdsip/8.5.1/lib", + "/usr/local/Ascend/nnal/atb/8.5.1/atb/cxx_abi_0/lib", + "/usr/local/Ascend/nnal/atb/latest/atb/cxx_abi_1/lib", + "/usr/local/Ascend/cann-8.5.0/lib64", + ] + assert paths[-1] == existing diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_require_npu_models.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_require_npu_models.py new file mode 100644 index 00000000..4b60b5bf --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_require_npu_models.py @@ -0,0 +1,229 @@ +from pathlib import Path + +import pytest + +from test_pdf_npu_ocr_priority import _Element, _load_process_module + + +def test_pdf_require_npu_models_rejects_missing_adapters(monkeypatch): + process = _load_process_module() + + monkeypatch.setattr(process, "partition_pdf", lambda **kwargs: [_Element("unused")]) + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: False) + + mapper = process.UnstructuredIOMapper(requireNpuModels=True) + + with pytest.raises(RuntimeError, match="NPU layout adapter is unavailable"): + mapper._extract_pdf(Path("sample.pdf")) + + +def test_pdf_require_npu_models_rejects_native_ocr_fallback(monkeypatch): + process = _load_process_module() + + monkeypatch.setattr(process, "partition_pdf", lambda **kwargs: [_Element("unused")]) + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) + process._NPU_OCR_ADAPTER_STATUS.update({"attempted": True, "npu": True, "ocr": True, "error": None}) + monkeypatch.setattr( + process, + "_get_ocr_runtime_status", + lambda: {"device": "npu", "native_only": True, "is_alive": False}, + ) + + mapper = process.UnstructuredIOMapper(requireNpuModels=True) + + with pytest.raises(RuntimeError, match="OCR NPU runtime is unavailable"): + mapper._extract_pdf(Path("sample.pdf")) + + +def test_docx_require_npu_models_uses_visual_npu_route(monkeypatch): + process = _load_process_module() + calls = [] + + monkeypatch.setattr(process, "_convert_office_to_pdf", lambda path: Path("converted.pdf")) + + def _extract_pdf(path): + calls.append(path) + return [{"index": 0, "category": "Title", "text": "converted"}], "pdf-npu-ocr-hi_res" + + mapper = process.UnstructuredIOMapper(requireNpuModels=True, enableDocxFastpath=True) + monkeypatch.setattr(mapper, "_extract_pdf", _extract_pdf) + + elements, mode = mapper._extract_elements(Path("sample.docx"), "docx") + + assert calls == [Path("converted.pdf")] + assert elements[0]["text"] == "converted" + assert mode == "docx-visual-pdf-npu-ocr-hi_res" + + +def test_docx_require_npu_models_rejects_non_npu_visual_route(monkeypatch): + process = _load_process_module() + + monkeypatch.setattr(process, "_convert_office_to_pdf", lambda path: Path("converted.pdf")) + + mapper = process.UnstructuredIOMapper(requireNpuModels=True, enableDocxFastpath=True) + monkeypatch.setattr( + mapper, + "_extract_pdf", + lambda path: ([_Element("fallback text")], "pdf-npu-ocr-fallback-fast"), + ) + + with pytest.raises(RuntimeError, match="DOCX visual NPU route did not use NPU OCR mode"): + mapper._extract_elements(Path("sample.docx"), "docx") + + +def test_docx_require_npu_models_rejects_npu_without_ocr(monkeypatch): + process = _load_process_module() + + monkeypatch.setattr(process, "_convert_office_to_pdf", lambda path: Path("converted.pdf")) + + mapper = process.UnstructuredIOMapper(requireNpuModels=True, enableDocxFastpath=True) + monkeypatch.setattr( + mapper, + "_extract_pdf", + lambda path: ([_Element("layout only")], "pdf-npu-hi_res"), + ) + + with pytest.raises(RuntimeError, match="DOCX visual NPU route did not use NPU OCR mode"): + mapper._extract_elements(Path("sample.docx"), "docx") + + +def test_docx_require_npu_models_fails_without_soffice(monkeypatch): + process = _load_process_module() + + monkeypatch.delenv("UNSTRUCTUREDIO_LIBREOFFICE_BIN", raising=False) + monkeypatch.setattr(process.shutil, "which", lambda name: None) + + with pytest.raises(RuntimeError, match="LibreOffice/soffice is required"): + process._convert_office_to_pdf(Path("sample.docx")) + + +def test_require_npu_models_disables_ocr_native_fallback(monkeypatch): + process = _load_process_module() + + monkeypatch.delenv("UNSTRUCTUREDIO_REQUIRE_NPU_MODELS", raising=False) + monkeypatch.delenv("OCR_ADAPTER_DISABLE_NATIVE_FALLBACK", raising=False) + + process.UnstructuredIOMapper(requireNpuModels=True) + + assert process.os.environ["UNSTRUCTUREDIO_REQUIRE_NPU_MODELS"] == "1" + assert process.os.environ["OCR_ADAPTER_DISABLE_NATIVE_FALLBACK"] == "1" + + +def test_strict_npu_ocr_runtime_requires_available_flag(): + process = _load_process_module() + + assert ( + process._is_strict_npu_ocr_runtime( + {"device": "npu", "native_only": False, "is_alive": True, "available": False} + ) + is False + ) + + +def test_apply_npu_ocr_adapters_prewarms_ocr_before_torch_npu(monkeypatch): + process = _load_process_module() + calls = [] + + class FakeNpuAdapter: + @staticmethod + def apply_patches(): + calls.append("npu") + + class FakeOcrAdapter: + @staticmethod + def apply_ocr_patch(): + calls.append("ocr_patch") + + @staticmethod + def get_ocr_runtime_status(): + calls.append("ocr_status") + return {"device": "npu", "native_only": False, "is_alive": True, "available": True} + + original_import = __import__ + + def fake_import(name, *args, **kwargs): + if name == "npu_adapter": + return FakeNpuAdapter + if name == "ocr_npu_adapter": + return FakeOcrAdapter + return original_import(name, *args, **kwargs) + + monkeypatch.setattr(process, "_configure_npu_ocr_environment", lambda: None) + monkeypatch.setattr(process.builtins, "__import__", fake_import) + process._NPU_OCR_ADAPTER_STATUS.update({"attempted": False, "npu": False, "ocr": False, "error": None}) + + assert process._apply_npu_ocr_adapters() is True + assert calls == ["ocr_patch", "ocr_status", "npu"] + + +def test_pdf_partition_is_imported_after_npu_adapters(monkeypatch): + process = _load_process_module() + calls = [] + + class FakePdfModule: + @staticmethod + def partition_pdf(**kwargs): + calls.append("partition_pdf") + return [ + _Element("long enough text from lazy pdf partition import path one"), + _Element("long enough text from lazy pdf partition import path two"), + _Element("long enough text from lazy pdf partition import path three"), + ] + + original_import = __import__ + + def fake_import(name, *args, **kwargs): + if name == "unstructured.partition.pdf": + calls.append("import_partition_pdf") + return FakePdfModule + return original_import(name, *args, **kwargs) + + monkeypatch.setattr(process, "partition_pdf", None) + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: calls.append("adapters") or True) + process._NPU_OCR_ADAPTER_STATUS.update({"attempted": True, "npu": True, "ocr": True, "error": None}) + monkeypatch.setattr( + process, + "_get_ocr_runtime_status", + lambda: {"device": "npu", "native_only": False, "is_alive": True, "available": True}, + ) + monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) + monkeypatch.setattr(process.builtins, "__import__", fake_import) + + mapper = process.UnstructuredIOMapper(requireNpuModels=True) + elements, mode = mapper._extract_pdf(Path("sample.pdf")) + + assert calls[:3] == ["adapters", "import_partition_pdf", "partition_pdf"] + assert mode == "pdf-npu-ocr-hi_res" + assert elements[0]["text"].startswith("long enough text") + + +def test_pdf_disables_table_structure_when_local_table_model_missing(monkeypatch): + process = _load_process_module() + seen_kwargs = [] + + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) + process._NPU_OCR_ADAPTER_STATUS.update({"attempted": True, "npu": True, "ocr": True, "error": None}) + monkeypatch.setattr( + process, + "_get_ocr_runtime_status", + lambda: {"device": "npu", "native_only": False, "is_alive": True, "available": True}, + ) + monkeypatch.setattr(process.Path, "exists", lambda self: False) + monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) + + def fake_partition_pdf(**kwargs): + seen_kwargs.append(kwargs) + return [ + _Element("long enough text from missing table model path one"), + _Element("long enough text from missing table model path two"), + _Element("long enough text from missing table model path three"), + ] + + monkeypatch.setattr(process, "partition_pdf", fake_partition_pdf) + + mapper = process.UnstructuredIOMapper(requireNpuModels=True, pdfInferTableStructure=True) + elements, mode = mapper._extract_pdf(Path("sample.pdf")) + + assert seen_kwargs[0]["infer_table_structure"] is False + assert mode == "pdf-npu-ocr-hi_res" + assert len(elements) == 3 diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_table_transformer_npu.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_table_transformer_npu.py new file mode 100644 index 00000000..7b283ebd --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_table_transformer_npu.py @@ -0,0 +1,162 @@ +import sys +import types + +from test_pdf_npu_ocr_priority import _load_process_module + + +def _install_fake_transformers(monkeypatch, calls): + transformers = types.ModuleType("transformers") + + class FakeProcessor: + @classmethod + def from_pretrained(cls, model_path, local_files_only=False): + calls.append(("processor", str(model_path), local_files_only)) + return cls() + + class FakeConfig: + last = None + + def __init__(self): + self.use_pretrained_backbone = True + FakeConfig.last = self + + @classmethod + def from_pretrained(cls, model_path, local_files_only=False): + calls.append(("config", str(model_path), local_files_only)) + return cls() + + class FakeModel: + def __init__(self, config): + calls.append(("model_init", config.use_pretrained_backbone)) + self.config = config + self.loaded = None + self.to_device = None + + def load_state_dict(self, state_dict, strict=False): + calls.append(("load_state_dict", state_dict, strict)) + self.loaded = state_dict + return [], [] + + def eval(self): + calls.append(("eval",)) + return self + + def to(self, device): + calls.append(("to", device)) + self.to_device = device + return self + + transformers.DetrImageProcessor = FakeProcessor + transformers.TableTransformerConfig = FakeConfig + transformers.TableTransformerForObjectDetection = FakeModel + monkeypatch.setitem(sys.modules, "transformers", transformers) + return FakeModel + + +def _install_fake_safetensors(monkeypatch, calls): + safetensors = types.ModuleType("safetensors") + safetensors_torch = types.ModuleType("safetensors.torch") + + def load_file(path, device="cpu"): + calls.append(("load_safetensors", str(path), device)) + return {"weight": "from-safetensors"} + + safetensors_torch.load_file = load_file + monkeypatch.setitem(sys.modules, "safetensors", safetensors) + monkeypatch.setitem(sys.modules, "safetensors.torch", safetensors_torch) + + +def test_table_transformer_loader_uses_config_state_dict_and_npu(monkeypatch, tmp_path): + process = _load_process_module() + calls = [] + model_cls = _install_fake_transformers(monkeypatch, calls) + _install_fake_safetensors(monkeypatch, calls) + (tmp_path / "model.safetensors").write_text("fake", encoding="utf-8") + + feature_extractor, model = process._load_local_table_transformer_model(tmp_path, "npu:0") + + assert feature_extractor is not None + assert isinstance(model, model_cls) + assert ("config", str(tmp_path), True) in calls + assert ("model_init", False) in calls + assert ("load_safetensors", str(tmp_path / "model.safetensors"), "cpu") in calls + assert ("load_state_dict", {"weight": "from-safetensors"}, False) in calls + assert ("to", "npu:0") in calls + assert model.to_device == "npu:0" + + +def test_pdf_runtime_overrides_initializes_table_agent_on_npu(monkeypatch, tmp_path): + process = _load_process_module() + calls = [] + _install_fake_transformers(monkeypatch, calls) + + unstructured_inference = types.ModuleType("unstructured_inference") + models_module = types.ModuleType("unstructured_inference.models") + tables_module = types.ModuleType("unstructured_inference.models.tables") + + class FakeTableAgent: + model = None + + class FakeTableTransformerModel: + initialize = lambda self, model=None, device="cpu": None + + tables_module.DEFAULT_MODEL = "old-model" + tables_module.tables_agent = FakeTableAgent() + tables_module.UnstructuredTableTransformerModel = FakeTableTransformerModel + tables_module.load_agent = lambda: None + models_module.tables = tables_module + unstructured_inference.models = models_module + monkeypatch.setitem(sys.modules, "unstructured_inference", unstructured_inference) + monkeypatch.setitem(sys.modules, "unstructured_inference.models", models_module) + monkeypatch.setitem(sys.modules, "unstructured_inference.models.tables", tables_module) + monkeypatch.setattr(process, "PDF_TABLE_MODEL_PATH", str(tmp_path)) + monkeypatch.setattr(process, "_select_table_transformer_device", lambda: "npu:0") + + def fake_loader(model_path, device): + calls.append(("loader", str(model_path), device)) + return "feature-extractor", "table-model" + + monkeypatch.setattr(process, "_load_local_table_transformer_model", fake_loader, raising=False) + + with process._pdf_runtime_overrides(): + tables_module.load_agent() + + assert ("loader", str(tmp_path), "npu:0") in calls + assert tables_module.tables_agent.device == "npu:0" + assert tables_module.tables_agent.feature_extractor == "feature-extractor" + assert tables_module.tables_agent.model == "table-model" + + +def test_pdf_runtime_overrides_rejects_cpu_table_device_in_strict_mode(monkeypatch, tmp_path): + process = _load_process_module() + + unstructured_inference = types.ModuleType("unstructured_inference") + models_module = types.ModuleType("unstructured_inference.models") + tables_module = types.ModuleType("unstructured_inference.models.tables") + + class FakeTableAgent: + model = None + + class FakeTableTransformerModel: + initialize = lambda self, model=None, device="cpu": None + + tables_module.DEFAULT_MODEL = "old-model" + tables_module.tables_agent = FakeTableAgent() + tables_module.UnstructuredTableTransformerModel = FakeTableTransformerModel + tables_module.load_agent = lambda: None + models_module.tables = tables_module + unstructured_inference.models = models_module + monkeypatch.setitem(sys.modules, "unstructured_inference", unstructured_inference) + monkeypatch.setitem(sys.modules, "unstructured_inference.models", models_module) + monkeypatch.setitem(sys.modules, "unstructured_inference.models.tables", tables_module) + monkeypatch.setattr(process, "PDF_TABLE_MODEL_PATH", str(tmp_path)) + monkeypatch.setattr(process, "_select_table_transformer_device", lambda: "cpu") + monkeypatch.setenv("UNSTRUCTUREDIO_REQUIRE_NPU_MODELS", "1") + + with process._pdf_runtime_overrides(): + try: + tables_module.load_agent() + except RuntimeError as exc: + assert "Table transformer NPU is required" in str(exc) + else: + raise AssertionError("strict mode accepted CPU table transformer device") From 7b4fcf34a25703c8091ec02dd9c38b35500d5991 Mon Sep 17 00:00:00 2001 From: qianqiuer <3418979384@qq.com> Date: Tue, 2 Jun 2026 21:59:51 +0800 Subject: [PATCH 3/5] Remove development tests from unstructuredio delivery --- .../unstructuredio/operator_src/README.md | 6 +- .../tests/check_docx_fastpath_coordinates.py | 76 ---- .../tests/test_check_npu_runtime.py | 65 --- .../tests/test_docx_fastpath_coordinates.py | 71 ---- .../tests/test_npu_adapter_cpu_fallback.py | 31 -- .../operator_src/tests/test_ocr_cpu_patch.py | 45 -- .../tests/test_pdf_npu_ocr_priority.py | 390 ------------------ .../tests/test_process_ascend_env.py | 27 -- .../tests/test_require_npu_models.py | 229 ---------- .../tests/test_table_transformer_npu.py | 162 -------- 10 files changed, 1 insertion(+), 1101 deletions(-) delete mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/check_docx_fastpath_coordinates.py delete mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_check_npu_runtime.py delete mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_docx_fastpath_coordinates.py delete mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_npu_adapter_cpu_fallback.py delete mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_ocr_cpu_patch.py delete mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_pdf_npu_ocr_priority.py delete mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_process_ascend_env.py delete mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_require_npu_models.py delete mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_table_transformer_npu.py diff --git a/runtime/ops/mapper/unstructuredio/operator_src/README.md b/runtime/ops/mapper/unstructuredio/operator_src/README.md index a81c372a..f0224964 100644 --- a/runtime/ops/mapper/unstructuredio/operator_src/README.md +++ b/runtime/ops/mapper/unstructuredio/operator_src/README.md @@ -39,11 +39,7 @@ ## 验证 -本地单测: - -```bash -python -m pytest operator_src/tests -q -``` +本目录不随交付提交开发期单测代码;验收测试样例保留在上一级 `test_cases/` 目录。 验收环境自检: diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/check_docx_fastpath_coordinates.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/check_docx_fastpath_coordinates.py deleted file mode 100644 index fd70300e..00000000 --- a/runtime/ops/mapper/unstructuredio/operator_src/tests/check_docx_fastpath_coordinates.py +++ /dev/null @@ -1,76 +0,0 @@ -import importlib.util -import sys -import types -from pathlib import Path - - -def _load_process_module(): - if "datamate" not in sys.modules: - datamate = types.ModuleType("datamate") - core = types.ModuleType("datamate.core") - base_op = types.ModuleType("datamate.core.base_op") - - class _Mapper: - def __init__(self, *args, **kwargs): - self.filepath_key = "filepath" - self.filetype_key = "filetype" - self.text_key = "text" - self.target_type_key = "target_type" - - base_op.Mapper = _Mapper - base_op.OPERATORS = [] - core.base_op = base_op - datamate.core = core - sys.modules["datamate"] = datamate - sys.modules["datamate.core"] = core - sys.modules["datamate.core.base_op"] = base_op - - if "unstructured" not in sys.modules: - unstructured = types.ModuleType("unstructured") - partition = types.ModuleType("unstructured.partition") - auto = types.ModuleType("unstructured.partition.auto") - - def _partition(*args, **kwargs): - raise NotImplementedError("partition stub should not be used in docx fastpath checks") - - auto.partition = _partition - partition.auto = auto - unstructured.partition = partition - sys.modules["unstructured"] = unstructured - sys.modules["unstructured.partition"] = partition - sys.modules["unstructured.partition.auto"] = auto - - module_path = Path(__file__).resolve().parents[1] / "process.py" - spec = importlib.util.spec_from_file_location("unstructuredio_process", module_path) - module = importlib.util.module_from_spec(spec) - assert spec is not None and spec.loader is not None - spec.loader.exec_module(module) - return module - - -def main(): - process = _load_process_module() - base = Path(__file__).resolve().parents[2] / "test_cases" / "example_input" - samples = [ - "docx_corpus_sample_1.docx", - "docx_corpus_sample_2.docx", - ] - failures = [] - for sample in samples: - elements = process._extract_docx_fastpath(base / sample) - if not elements: - failures.append(f"{sample}: no elements") - continue - if not any(item.get("coordinates") for item in elements): - failures.append(f"{sample}: all coordinates are null") - if not all(item.get("page_number") is not None for item in elements): - failures.append(f"{sample}: contains null page_number") - - if failures: - raise SystemExit("\n".join(failures)) - - print("docx fastpath coordinate checks passed") - - -if __name__ == "__main__": - main() diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_check_npu_runtime.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_check_npu_runtime.py deleted file mode 100644 index 0f347920..00000000 --- a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_check_npu_runtime.py +++ /dev/null @@ -1,65 +0,0 @@ -import importlib.util -import subprocess -from pathlib import Path - - -def _load_check_module(): - module_path = Path(__file__).resolve().parents[1] / "check_npu_runtime.py" - spec = importlib.util.spec_from_file_location("check_npu_runtime_under_test", module_path) - module = importlib.util.module_from_spec(spec) - assert spec is not None and spec.loader is not None - spec.loader.exec_module(module) - return module - - -def test_module_probe_runs_each_import_in_isolated_process(monkeypatch): - check = _load_check_module() - commands = [] - - def fake_run(command, **kwargs): - commands.append(command) - return subprocess.CompletedProcess(command, 0, stdout='{"available": true, "version": "x"}\n', stderr="") - - monkeypatch.setattr(check.subprocess, "run", fake_run) - - assert check._module_version("torch_npu") == {"available": True, "version": "x"} - assert commands[0][0] == check.sys.executable - assert "importlib.import_module('torch_npu')" in commands[0][2] - - -def test_main_accepts_split_torch_and_paddle_npu_probe_success(monkeypatch, tmp_path, capsys): - check = _load_check_module() - model_dir = tmp_path / "model" - model_dir.mkdir() - - monkeypatch.setattr(check, "_module_version", lambda name: {"available": True, "version": name}) - monkeypatch.setenv("UNSTRUCTUREDIO_YOLOX_MODEL_PATH", str(model_dir)) - monkeypatch.setenv("UNSTRUCTUREDIO_YOLOX_SRC_PATH", str(model_dir)) - monkeypatch.setenv("UNSTRUCTUREDIO_OCR_DET_MODEL_DIR", str(model_dir)) - monkeypatch.setenv("UNSTRUCTUREDIO_OCR_REC_MODEL_DIR", str(model_dir)) - monkeypatch.setenv("UNSTRUCTUREDIO_OCR_CLS_MODEL_DIR", str(model_dir)) - - assert check.main() == 0 - report = capsys.readouterr().out - assert '"torch_npu"' in report - assert '"paddleocr"' in report - - -def test_module_probe_injects_ascend_library_paths(monkeypatch): - check = _load_check_module() - seen_envs = [] - - def fake_exists(path): - return path in {"/opt/ascend/lib", "/tmp/existing"} - - def fake_run(command, **kwargs): - seen_envs.append(kwargs["env"]) - return subprocess.CompletedProcess(command, 0, stdout='{"available": true, "version": "x"}\n', stderr="") - - monkeypatch.setattr(check.os.path, "exists", fake_exists) - monkeypatch.setattr(check, "ASCEND_NPU_LIBRARY_PATHS", ("/opt/ascend/lib", "/missing")) - monkeypatch.setenv("LD_LIBRARY_PATH", "/tmp/existing") - monkeypatch.setattr(check.subprocess, "run", fake_run) - - assert check._module_version("paddle")["available"] is True - assert seen_envs[0]["LD_LIBRARY_PATH"].split(":") == ["/opt/ascend/lib", "/tmp/existing"] diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_docx_fastpath_coordinates.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_docx_fastpath_coordinates.py deleted file mode 100644 index 26eff009..00000000 --- a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_docx_fastpath_coordinates.py +++ /dev/null @@ -1,71 +0,0 @@ -import importlib.util -import sys -import types -from pathlib import Path - - -def _load_process_module(): - if "datamate" not in sys.modules: - datamate = types.ModuleType("datamate") - core = types.ModuleType("datamate.core") - base_op = types.ModuleType("datamate.core.base_op") - - class _Mapper: - def __init__(self, *args, **kwargs): - self.filepath_key = "filepath" - self.filetype_key = "filetype" - self.text_key = "text" - self.target_type_key = "target_type" - - base_op.Mapper = _Mapper - core.base_op = base_op - datamate.core = core - sys.modules["datamate"] = datamate - sys.modules["datamate.core"] = core - sys.modules["datamate.core.base_op"] = base_op - - if "unstructured" not in sys.modules: - unstructured = types.ModuleType("unstructured") - partition = types.ModuleType("unstructured.partition") - auto = types.ModuleType("unstructured.partition.auto") - - def _partition(*args, **kwargs): - raise NotImplementedError("partition stub should not be used in docx fastpath tests") - - auto.partition = _partition - partition.auto = auto - unstructured.partition = partition - sys.modules["unstructured"] = unstructured - sys.modules["unstructured.partition"] = partition - sys.modules["unstructured.partition.auto"] = auto - - module_path = Path(__file__).resolve().parents[1] / "process.py" - spec = importlib.util.spec_from_file_location("unstructuredio_process", module_path) - module = importlib.util.module_from_spec(spec) - assert spec is not None and spec.loader is not None - spec.loader.exec_module(module) - return module - - -process = _load_process_module() -TEST_INPUT_DIR = Path(__file__).resolve().parents[2] / "test_cases" / "example_input" - - -def _extract(sample_name: str): - return process._extract_docx_fastpath(TEST_INPUT_DIR / sample_name) - - -def test_docx_corpus_sample_1_coordinates_are_not_all_null(): - elements = _extract("docx_corpus_sample_1.docx") - - assert elements - assert any(item.get("coordinates") for item in elements) - assert all(item.get("page_number") is not None for item in elements) - - -def test_docx_corpus_sample_2_coordinates_are_not_all_null(): - elements = _extract("docx_corpus_sample_2.docx") - - assert elements - assert any(item.get("coordinates") for item in elements) - assert any(item.get("category") == "Table" for item in elements) diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_npu_adapter_cpu_fallback.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_npu_adapter_cpu_fallback.py deleted file mode 100644 index 12ea3453..00000000 --- a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_npu_adapter_cpu_fallback.py +++ /dev/null @@ -1,31 +0,0 @@ -import importlib.util -import sys -import types -from pathlib import Path - - -def _load_npu_adapter(): - if "torch_npu" not in sys.modules: - sys.modules["torch_npu"] = types.ModuleType("torch_npu") - module_path = Path(__file__).resolve().parents[1] / "adapters" / "npu_adapter.py" - spec = importlib.util.spec_from_file_location("npu_adapter_under_test", module_path) - module = importlib.util.module_from_spec(spec) - assert spec is not None and spec.loader is not None - spec.loader.exec_module(module) - return module - - -def test_npu_get_model_delegates_to_original_loader_when_cpu_forced_and_local_model_missing(monkeypatch): - adapter = _load_npu_adapter() - calls = [] - - def original_get_model(model_name, **kwargs): - calls.append((model_name, kwargs)) - return "cpu-model" - - adapter._ORIGINAL_GET_MODEL = original_get_model - monkeypatch.setattr(adapter, "_resolve_yolox_model_path", lambda: str(Path("missing.pt"))) - monkeypatch.setenv("UNSTRUCTUREDIO_FORCE_CPU_MODELS", "1") - - assert adapter.npu_get_model("yolox", foo="bar", password="secret") == "cpu-model" - assert calls == [("yolox", {"foo": "bar"})] diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_ocr_cpu_patch.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_ocr_cpu_patch.py deleted file mode 100644 index 8362d754..00000000 --- a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_ocr_cpu_patch.py +++ /dev/null @@ -1,45 +0,0 @@ -import importlib.util -from pathlib import Path - - -def _load_ocr_adapter(): - module_path = Path(__file__).resolve().parents[1] / "adapters" / "ocr_npu_adapter.py" - spec = importlib.util.spec_from_file_location("ocr_adapter_under_test", module_path) - module = importlib.util.module_from_spec(spec) - assert spec is not None and spec.loader is not None - spec.loader.exec_module(module) - return module - - -def test_force_paddle_cpu_patch_does_not_require_native_tesseract(monkeypatch): - adapter = _load_ocr_adapter() - - def fail_native_load(): - raise ModuleNotFoundError("pytesseract") - - monkeypatch.setattr(adapter, "_load_native_tesseract_modules", fail_native_load) - monkeypatch.setenv("OCR_ADAPTER_FORCE_PADDLE_CPU", "1") - - adapter.apply_ocr_patch() - - assert "pytesseract" in adapter.sys.modules - assert "unstructured_pytesseract" in adapter.sys.modules - - -def test_cpu_paddle_availability_check_does_not_import_paddle_in_parent(monkeypatch): - adapter = _load_ocr_adapter() - imported = [] - - def fake_find_spec(name): - return object() if name in {"paddle", "paddleocr"} else None - - def fail_import(name): - imported.append(name) - raise AssertionError("parent process must not import paddle for CPU OCR availability") - - monkeypatch.setattr(adapter.importlib.util, "find_spec", fake_find_spec) - monkeypatch.setattr(adapter.importlib, "import_module", fail_import) - monkeypatch.setenv("OCR_ADAPTER_DEVICE", "cpu") - - assert adapter._paddle_ocr_available() is True - assert imported == [] diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_pdf_npu_ocr_priority.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_pdf_npu_ocr_priority.py deleted file mode 100644 index 60584957..00000000 --- a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_pdf_npu_ocr_priority.py +++ /dev/null @@ -1,390 +0,0 @@ -import importlib.util -import os -import sys -import types -from pathlib import Path - - -def _load_process_module(): - datamate = types.ModuleType("datamate") - core = types.ModuleType("datamate.core") - base_op = types.ModuleType("datamate.core.base_op") - - class _Mapper: - def __init__(self, *args, **kwargs): - self.filepath_key = "filepath" - self.filetype_key = "filetype" - self.text_key = "text" - self.target_type_key = "target_type" - - base_op.Mapper = _Mapper - core.base_op = base_op - datamate.core = core - sys.modules["datamate"] = datamate - sys.modules["datamate.core"] = core - sys.modules["datamate.core.base_op"] = base_op - - if "unstructured" not in sys.modules: - unstructured = types.ModuleType("unstructured") - partition = types.ModuleType("unstructured.partition") - auto = types.ModuleType("unstructured.partition.auto") - - def _partition(*args, **kwargs): - raise NotImplementedError("partition_auto stub should not be used in these tests") - - auto.partition = _partition - partition.auto = auto - unstructured.partition = partition - sys.modules["unstructured"] = unstructured - sys.modules["unstructured.partition"] = partition - sys.modules["unstructured.partition.auto"] = auto - - module_path = Path(__file__).resolve().parents[1] / "process.py" - spec = importlib.util.spec_from_file_location("unstructuredio_process_under_test", module_path) - module = importlib.util.module_from_spec(spec) - assert spec is not None and spec.loader is not None - spec.loader.exec_module(module) - return module - - -class _Metadata: - page_number = 1 - coordinates = None - text_as_html = None - - -class _Element: - category = "NarrativeText" - metadata = _Metadata() - - def __init__(self, text): - self.text = text - - -def test_process_disables_nltk_auto_download_before_unstructured_import(monkeypatch): - monkeypatch.delenv("AUTO_DOWNLOAD_NLTK", raising=False) - - _load_process_module() - - assert os.environ["AUTO_DOWNLOAD_NLTK"] == "False" - - -def test_pdf_keeps_fast_result_when_auto_fallback_raises(monkeypatch): - process = _load_process_module() - calls = [] - - monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) - monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) - monkeypatch.setattr(process, "_get_ocr_runtime_status", lambda: {"available": False, "device": "npu"}) - - def _partition_pdf(**kwargs): - calls.append(kwargs["strategy"]) - if kwargs["strategy"] == "auto": - raise RuntimeError("simulated auto fallback failure") - return [_Element("x"), _Element("y"), _Element("z")] - - monkeypatch.setattr(process, "partition_pdf", _partition_pdf) - - mapper = process.UnstructuredIOMapper(pdfStrategy="auto") - elements, mode = mapper._extract_pdf(Path("sample.pdf")) - - assert calls == ["fast", "auto"] - assert mode == "pdf-npu-ocr-fallback-fast" - assert [item["text"] for item in elements] == ["x", "y", "z"] - - -def test_pdf_skips_cpu_hi_res_model_fallback_even_when_cpu_ocr_exists(monkeypatch): - process = _load_process_module() - calls = [] - - monkeypatch.delenv("UNSTRUCTUREDIO_TABLE_DEVICE", raising=False) - monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) - monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) - monkeypatch.setattr(process, "_has_cpu_ocr_runtime", lambda: True) - monkeypatch.setattr(process, "_get_ocr_runtime_status", lambda: {"available": False, "device": "npu"}) - - def _partition_pdf(**kwargs): - calls.append( - { - "strategy": kwargs["strategy"], - "hi_res_model_name": kwargs.get("hi_res_model_name"), - "table_device": process.os.environ.get("UNSTRUCTUREDIO_TABLE_DEVICE"), - } - ) - return [ - _Element("long enough text from fast fallback one with useful content"), - _Element("long enough text from fast fallback two with useful content"), - _Element("long enough text from fast fallback three with useful content"), - ] - - monkeypatch.setattr(process, "partition_pdf", _partition_pdf) - - mapper = process.UnstructuredIOMapper(pdfStrategy="auto") - elements, mode = mapper._extract_pdf(Path("sample.pdf")) - - assert calls == [{"strategy": "fast", "hi_res_model_name": None, "table_device": None}] - assert mode == "pdf-npu-ocr-fallback-fast" - assert len(elements) == 3 - - -def test_pdf_skips_cpu_hi_res_when_cpu_ocr_runtime_missing(monkeypatch): - process = _load_process_module() - calls = [] - - monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) - monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) - monkeypatch.setattr(process, "_has_cpu_ocr_runtime", lambda: False) - monkeypatch.setattr(process, "_get_ocr_runtime_status", lambda: {"available": False, "device": "npu"}) - - def _partition_pdf(**kwargs): - calls.append(kwargs["strategy"]) - return [ - _Element("fast text one with enough useful extracted content"), - _Element("fast text two with enough useful extracted content"), - _Element("fast text three with enough useful extracted content"), - ] - - monkeypatch.setattr(process, "partition_pdf", _partition_pdf) - - mapper = process.UnstructuredIOMapper(pdfStrategy="auto") - elements, mode = mapper._extract_pdf(Path("sample.pdf")) - - assert calls == ["fast"] - assert mode == "pdf-npu-ocr-fallback-fast" - assert len(elements) == 3 - - -def test_pdf_runs_npu_hi_res_when_npu_ocr_is_available(monkeypatch): - process = _load_process_module() - seen_kwargs = [] - - monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) - process._NPU_OCR_ADAPTER_STATUS.update({"attempted": True, "npu": True, "ocr": True, "error": None}) - monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) - monkeypatch.setattr( - process, - "_get_ocr_runtime_status", - lambda: {"available": True, "device": "npu", "native_only": False, "is_alive": True}, - ) - - def _partition_pdf(**kwargs): - seen_kwargs.append(kwargs) - return [ - _Element("long enough npu layout text one with useful extracted content"), - _Element("long enough npu layout text two with useful extracted content"), - _Element("long enough npu layout text three with useful extracted content"), - ] - - monkeypatch.setattr(process, "partition_pdf", _partition_pdf) - - mapper = process.UnstructuredIOMapper(pdfStrategy="auto") - elements, mode = mapper._extract_pdf(Path("sample.pdf")) - - assert seen_kwargs[0]["strategy"] == "hi_res" - assert seen_kwargs[0]["hi_res_model_name"] == "yolox" - assert seen_kwargs[0]["ocr_strategy"] == "force" - assert seen_kwargs[0]["ocr_mode"] == "entire_page" - assert mode == "pdf-npu-ocr-hi_res" - assert len(elements) == 3 - - -def test_pdf_uses_fast_path_when_ocr_adapter_is_unavailable(monkeypatch): - process = _load_process_module() - seen_kwargs = [] - - def apply_partial_adapters(): - process._NPU_OCR_ADAPTER_STATUS.update( - {"attempted": True, "npu": True, "ocr": False, "error": "ocr unavailable"} - ) - return False - - monkeypatch.setattr(process, "_apply_npu_ocr_adapters", apply_partial_adapters) - monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) - monkeypatch.setattr(process, "_get_ocr_runtime_status", lambda: {"available": False}) - - def _partition_pdf(**kwargs): - seen_kwargs.append(kwargs) - return [ - _Element("long enough npu layout text one with useful extracted content"), - _Element("long enough npu layout text two with useful extracted content"), - _Element("long enough npu layout text three with useful extracted content"), - ] - - monkeypatch.setattr(process, "partition_pdf", _partition_pdf) - - mapper = process.UnstructuredIOMapper(pdfStrategy="auto") - elements, mode = mapper._extract_pdf(Path("sample.pdf")) - - assert seen_kwargs[0]["strategy"] == "fast" - assert "hi_res_model_name" not in seen_kwargs[0] - assert "ocr_strategy" not in seen_kwargs[0] - assert mode == "pdf-npu-ocr-fallback-fast" - assert len(elements) == 3 - - -def test_pdf_falls_back_when_table_caption_has_no_table(monkeypatch): - process = _load_process_module() - calls = [] - - monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) - monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) - monkeypatch.setattr(process, "_has_cpu_ocr_runtime", lambda: False) - monkeypatch.setattr(process, "_get_ocr_runtime_status", lambda: {"available": True, "device": "npu", "native_only": False, "is_alive": True}) - - def _partition_pdf(**kwargs): - calls.append(kwargs["strategy"]) - if kwargs["strategy"] == "hi_res": - return [ - _Element("Attention Is All You Need"), - _Element( - "Table 3: Variations on the Transformer architecture. " - "This line says a table exists but the model did not return a Table element." - ), - _Element("long enough surrounding text with useful extracted content"), - ] - return [ - _Element("fast text one with enough useful extracted content"), - _Element("Table 3: Variations BLEU PPL params 25.8 4.92 65M 26.4 4.75 80M"), - _Element("fast text three with enough useful extracted content"), - ] - - monkeypatch.setattr(process, "partition_pdf", _partition_pdf) - - mapper = process.UnstructuredIOMapper(pdfStrategy="auto") - elements, mode = mapper._extract_pdf(Path("sample.pdf")) - - assert calls[:2] == ["hi_res", "fast"] - assert mode == "pdf-npu-ocr-fallback-fast" - assert any(item["category"] == "Table" for item in elements) - - -def test_pdf_table_body_heuristic_rejects_numeric_citation_paragraph(): - process = _load_process_module() - - text = ( - "Recurrent neural networks, long short-term memory [13] and gated recurrent [7] " - "neural networks in particular, have been firmly established as state of the art " - "approaches in sequence modeling and transduction problems such as language " - "modeling and machine translation [35, 2, 5]. Numerous efforts have since " - "continued to push the boundaries of recurrent language models and encoder-decoder " - "architectures [38, 24, 15]." - ) - - assert process._looks_like_table_body(text) is False - - -def test_pdf_table_body_heuristic_accepts_dense_numeric_table_row(): - process = _load_process_module() - - text = ( - "PPL train steps (dev) 100K 4.92 5.29 5.00 4.91 5.01 5.16 5.01 " - "6.11 5.19 4.88 5.75 4.66 5.12 4.75 5.77 4.95 4.67 5.47 4.92 300K 4.33" - ) - - assert process._looks_like_table_body(text) is True - - -def test_existing_pdf_table_gets_html_when_missing(): - process = _load_process_module() - - items = [ - { - "category": "Table", - "text": "Layer Type Complexity O(n) Self-Attention O(n².d)", - "text_as_html": None, - } - ] - - promoted = process._promote_obvious_pdf_tables(items) - - assert promoted[0]["category"] == "Table" - assert promoted[0]["text_as_html"].startswith("
    ") - - -def test_npu_mode_name_does_not_treat_cpu_ocr_as_npu(monkeypatch): - process = _load_process_module() - process._NPU_OCR_ADAPTER_STATUS.update({"npu": True, "ocr": True}) - monkeypatch.setattr( - process, - "_get_ocr_runtime_status", - lambda: {"available": True, "device": "cpu", "native_only": False, "is_alive": True}, - ) - - assert process._npu_ocr_mode_name() == "pdf-npu-hi_res" - - -def test_apply_adapters_prewarms_cpu_ocr_before_npu_adapter(monkeypatch): - process = _load_process_module() - calls = [] - - fake_ocr = types.ModuleType("ocr_npu_adapter") - - def apply_ocr_patch(): - calls.append("ocr_patch") - - def prewarm_ocr_runtime(): - calls.append("ocr_prewarm") - return {"available": True, "device": "cpu", "native_only": False, "is_alive": True} - - def get_ocr_runtime_status(): - calls.append("ocr_status") - return {"available": True, "device": "cpu", "native_only": False, "is_alive": True} - - fake_ocr.apply_ocr_patch = apply_ocr_patch - fake_ocr.prewarm_ocr_runtime = prewarm_ocr_runtime - fake_ocr.get_ocr_runtime_status = get_ocr_runtime_status - - fake_npu = types.ModuleType("npu_adapter") - - def apply_patches(): - calls.append("npu_patch") - - fake_npu.apply_patches = apply_patches - - monkeypatch.setitem(sys.modules, "ocr_npu_adapter", fake_ocr) - monkeypatch.setitem(sys.modules, "npu_adapter", fake_npu) - monkeypatch.setenv("UNSTRUCTUREDIO_OCR_DEVICE", "cpu") - monkeypatch.setenv("OCR_ADAPTER_FORCE_PADDLE_CPU", "1") - monkeypatch.setenv("UNSTRUCTUREDIO_ENABLE_CPU_OCR_FALLBACK", "1") - - assert process._apply_npu_ocr_adapters() is True - assert calls == ["ocr_patch", "ocr_prewarm", "npu_patch"] - assert process._NPU_OCR_ADAPTER_STATUS["ocr"] is True - assert process._NPU_OCR_ADAPTER_STATUS["npu"] is True - - -def test_apply_adapters_does_not_prewarm_default_npu_ocr(monkeypatch): - process = _load_process_module() - calls = [] - - fake_ocr = types.ModuleType("ocr_npu_adapter") - fake_ocr.apply_ocr_patch = lambda: calls.append("ocr_patch") - fake_ocr.prewarm_ocr_runtime = lambda: calls.append("ocr_prewarm") - fake_ocr.get_ocr_runtime_status = lambda: {"available": False, "device": "npu"} - - fake_npu = types.ModuleType("npu_adapter") - fake_npu.apply_patches = lambda: calls.append("npu_patch") - - monkeypatch.setitem(sys.modules, "ocr_npu_adapter", fake_ocr) - monkeypatch.setitem(sys.modules, "npu_adapter", fake_npu) - monkeypatch.delenv("UNSTRUCTUREDIO_OCR_DEVICE", raising=False) - monkeypatch.delenv("OCR_ADAPTER_DEVICE", raising=False) - - assert process._apply_npu_ocr_adapters() is True - assert calls == ["ocr_patch", "npu_patch"] - - -def test_configure_npu_ocr_environment_overrides_cpu_ocr_request(monkeypatch): - process = _load_process_module() - - monkeypatch.setenv("UNSTRUCTUREDIO_OCR_DEVICE", "cpu") - monkeypatch.setenv("OCR_ADAPTER_DEVICE", "cpu") - monkeypatch.setenv("OCR_ADAPTER_FORCE_PADDLE_CPU", "1") - monkeypatch.delenv("UNSTRUCTUREDIO_ENABLE_CPU_OCR_FALLBACK", raising=False) - monkeypatch.setattr(process, "_prepend_existing_sys_path", lambda path: None) - monkeypatch.setattr(process, "_configure_ascend_runtime_environment", lambda: None) - - process._configure_npu_ocr_environment() - - assert process.os.environ["OCR_ADAPTER_DEVICE"] == "npu" - assert process.os.environ["OCR_ADAPTER_DISABLE_NATIVE_FALLBACK"] == "1" diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_process_ascend_env.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_process_ascend_env.py deleted file mode 100644 index 2a454a01..00000000 --- a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_process_ascend_env.py +++ /dev/null @@ -1,27 +0,0 @@ -from test_pdf_npu_ocr_priority import _load_process_module - - -def test_process_ascend_env_includes_nnal_and_cann_variants(monkeypatch): - process = _load_process_module() - existing = "/tmp/existing_ld" - accepted = { - "/usr/local/Ascend/nnal/asdsip/8.5.1/lib", - "/usr/local/Ascend/nnal/atb/8.5.1/atb/cxx_abi_0/lib", - "/usr/local/Ascend/nnal/atb/latest/atb/cxx_abi_1/lib", - "/usr/local/Ascend/cann-8.5.0/lib64", - existing, - } - - monkeypatch.setenv("LD_LIBRARY_PATH", existing) - monkeypatch.setattr(process.os.path, "exists", lambda path: path in accepted) - - process._configure_ascend_runtime_environment() - - paths = process.os.environ["LD_LIBRARY_PATH"].split(":") - assert paths[:4] == [ - "/usr/local/Ascend/nnal/asdsip/8.5.1/lib", - "/usr/local/Ascend/nnal/atb/8.5.1/atb/cxx_abi_0/lib", - "/usr/local/Ascend/nnal/atb/latest/atb/cxx_abi_1/lib", - "/usr/local/Ascend/cann-8.5.0/lib64", - ] - assert paths[-1] == existing diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_require_npu_models.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_require_npu_models.py deleted file mode 100644 index 4b60b5bf..00000000 --- a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_require_npu_models.py +++ /dev/null @@ -1,229 +0,0 @@ -from pathlib import Path - -import pytest - -from test_pdf_npu_ocr_priority import _Element, _load_process_module - - -def test_pdf_require_npu_models_rejects_missing_adapters(monkeypatch): - process = _load_process_module() - - monkeypatch.setattr(process, "partition_pdf", lambda **kwargs: [_Element("unused")]) - monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: False) - - mapper = process.UnstructuredIOMapper(requireNpuModels=True) - - with pytest.raises(RuntimeError, match="NPU layout adapter is unavailable"): - mapper._extract_pdf(Path("sample.pdf")) - - -def test_pdf_require_npu_models_rejects_native_ocr_fallback(monkeypatch): - process = _load_process_module() - - monkeypatch.setattr(process, "partition_pdf", lambda **kwargs: [_Element("unused")]) - monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) - process._NPU_OCR_ADAPTER_STATUS.update({"attempted": True, "npu": True, "ocr": True, "error": None}) - monkeypatch.setattr( - process, - "_get_ocr_runtime_status", - lambda: {"device": "npu", "native_only": True, "is_alive": False}, - ) - - mapper = process.UnstructuredIOMapper(requireNpuModels=True) - - with pytest.raises(RuntimeError, match="OCR NPU runtime is unavailable"): - mapper._extract_pdf(Path("sample.pdf")) - - -def test_docx_require_npu_models_uses_visual_npu_route(monkeypatch): - process = _load_process_module() - calls = [] - - monkeypatch.setattr(process, "_convert_office_to_pdf", lambda path: Path("converted.pdf")) - - def _extract_pdf(path): - calls.append(path) - return [{"index": 0, "category": "Title", "text": "converted"}], "pdf-npu-ocr-hi_res" - - mapper = process.UnstructuredIOMapper(requireNpuModels=True, enableDocxFastpath=True) - monkeypatch.setattr(mapper, "_extract_pdf", _extract_pdf) - - elements, mode = mapper._extract_elements(Path("sample.docx"), "docx") - - assert calls == [Path("converted.pdf")] - assert elements[0]["text"] == "converted" - assert mode == "docx-visual-pdf-npu-ocr-hi_res" - - -def test_docx_require_npu_models_rejects_non_npu_visual_route(monkeypatch): - process = _load_process_module() - - monkeypatch.setattr(process, "_convert_office_to_pdf", lambda path: Path("converted.pdf")) - - mapper = process.UnstructuredIOMapper(requireNpuModels=True, enableDocxFastpath=True) - monkeypatch.setattr( - mapper, - "_extract_pdf", - lambda path: ([_Element("fallback text")], "pdf-npu-ocr-fallback-fast"), - ) - - with pytest.raises(RuntimeError, match="DOCX visual NPU route did not use NPU OCR mode"): - mapper._extract_elements(Path("sample.docx"), "docx") - - -def test_docx_require_npu_models_rejects_npu_without_ocr(monkeypatch): - process = _load_process_module() - - monkeypatch.setattr(process, "_convert_office_to_pdf", lambda path: Path("converted.pdf")) - - mapper = process.UnstructuredIOMapper(requireNpuModels=True, enableDocxFastpath=True) - monkeypatch.setattr( - mapper, - "_extract_pdf", - lambda path: ([_Element("layout only")], "pdf-npu-hi_res"), - ) - - with pytest.raises(RuntimeError, match="DOCX visual NPU route did not use NPU OCR mode"): - mapper._extract_elements(Path("sample.docx"), "docx") - - -def test_docx_require_npu_models_fails_without_soffice(monkeypatch): - process = _load_process_module() - - monkeypatch.delenv("UNSTRUCTUREDIO_LIBREOFFICE_BIN", raising=False) - monkeypatch.setattr(process.shutil, "which", lambda name: None) - - with pytest.raises(RuntimeError, match="LibreOffice/soffice is required"): - process._convert_office_to_pdf(Path("sample.docx")) - - -def test_require_npu_models_disables_ocr_native_fallback(monkeypatch): - process = _load_process_module() - - monkeypatch.delenv("UNSTRUCTUREDIO_REQUIRE_NPU_MODELS", raising=False) - monkeypatch.delenv("OCR_ADAPTER_DISABLE_NATIVE_FALLBACK", raising=False) - - process.UnstructuredIOMapper(requireNpuModels=True) - - assert process.os.environ["UNSTRUCTUREDIO_REQUIRE_NPU_MODELS"] == "1" - assert process.os.environ["OCR_ADAPTER_DISABLE_NATIVE_FALLBACK"] == "1" - - -def test_strict_npu_ocr_runtime_requires_available_flag(): - process = _load_process_module() - - assert ( - process._is_strict_npu_ocr_runtime( - {"device": "npu", "native_only": False, "is_alive": True, "available": False} - ) - is False - ) - - -def test_apply_npu_ocr_adapters_prewarms_ocr_before_torch_npu(monkeypatch): - process = _load_process_module() - calls = [] - - class FakeNpuAdapter: - @staticmethod - def apply_patches(): - calls.append("npu") - - class FakeOcrAdapter: - @staticmethod - def apply_ocr_patch(): - calls.append("ocr_patch") - - @staticmethod - def get_ocr_runtime_status(): - calls.append("ocr_status") - return {"device": "npu", "native_only": False, "is_alive": True, "available": True} - - original_import = __import__ - - def fake_import(name, *args, **kwargs): - if name == "npu_adapter": - return FakeNpuAdapter - if name == "ocr_npu_adapter": - return FakeOcrAdapter - return original_import(name, *args, **kwargs) - - monkeypatch.setattr(process, "_configure_npu_ocr_environment", lambda: None) - monkeypatch.setattr(process.builtins, "__import__", fake_import) - process._NPU_OCR_ADAPTER_STATUS.update({"attempted": False, "npu": False, "ocr": False, "error": None}) - - assert process._apply_npu_ocr_adapters() is True - assert calls == ["ocr_patch", "ocr_status", "npu"] - - -def test_pdf_partition_is_imported_after_npu_adapters(monkeypatch): - process = _load_process_module() - calls = [] - - class FakePdfModule: - @staticmethod - def partition_pdf(**kwargs): - calls.append("partition_pdf") - return [ - _Element("long enough text from lazy pdf partition import path one"), - _Element("long enough text from lazy pdf partition import path two"), - _Element("long enough text from lazy pdf partition import path three"), - ] - - original_import = __import__ - - def fake_import(name, *args, **kwargs): - if name == "unstructured.partition.pdf": - calls.append("import_partition_pdf") - return FakePdfModule - return original_import(name, *args, **kwargs) - - monkeypatch.setattr(process, "partition_pdf", None) - monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: calls.append("adapters") or True) - process._NPU_OCR_ADAPTER_STATUS.update({"attempted": True, "npu": True, "ocr": True, "error": None}) - monkeypatch.setattr( - process, - "_get_ocr_runtime_status", - lambda: {"device": "npu", "native_only": False, "is_alive": True, "available": True}, - ) - monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) - monkeypatch.setattr(process.builtins, "__import__", fake_import) - - mapper = process.UnstructuredIOMapper(requireNpuModels=True) - elements, mode = mapper._extract_pdf(Path("sample.pdf")) - - assert calls[:3] == ["adapters", "import_partition_pdf", "partition_pdf"] - assert mode == "pdf-npu-ocr-hi_res" - assert elements[0]["text"].startswith("long enough text") - - -def test_pdf_disables_table_structure_when_local_table_model_missing(monkeypatch): - process = _load_process_module() - seen_kwargs = [] - - monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) - process._NPU_OCR_ADAPTER_STATUS.update({"attempted": True, "npu": True, "ocr": True, "error": None}) - monkeypatch.setattr( - process, - "_get_ocr_runtime_status", - lambda: {"device": "npu", "native_only": False, "is_alive": True, "available": True}, - ) - monkeypatch.setattr(process.Path, "exists", lambda self: False) - monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) - - def fake_partition_pdf(**kwargs): - seen_kwargs.append(kwargs) - return [ - _Element("long enough text from missing table model path one"), - _Element("long enough text from missing table model path two"), - _Element("long enough text from missing table model path three"), - ] - - monkeypatch.setattr(process, "partition_pdf", fake_partition_pdf) - - mapper = process.UnstructuredIOMapper(requireNpuModels=True, pdfInferTableStructure=True) - elements, mode = mapper._extract_pdf(Path("sample.pdf")) - - assert seen_kwargs[0]["infer_table_structure"] is False - assert mode == "pdf-npu-ocr-hi_res" - assert len(elements) == 3 diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_table_transformer_npu.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_table_transformer_npu.py deleted file mode 100644 index 7b283ebd..00000000 --- a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_table_transformer_npu.py +++ /dev/null @@ -1,162 +0,0 @@ -import sys -import types - -from test_pdf_npu_ocr_priority import _load_process_module - - -def _install_fake_transformers(monkeypatch, calls): - transformers = types.ModuleType("transformers") - - class FakeProcessor: - @classmethod - def from_pretrained(cls, model_path, local_files_only=False): - calls.append(("processor", str(model_path), local_files_only)) - return cls() - - class FakeConfig: - last = None - - def __init__(self): - self.use_pretrained_backbone = True - FakeConfig.last = self - - @classmethod - def from_pretrained(cls, model_path, local_files_only=False): - calls.append(("config", str(model_path), local_files_only)) - return cls() - - class FakeModel: - def __init__(self, config): - calls.append(("model_init", config.use_pretrained_backbone)) - self.config = config - self.loaded = None - self.to_device = None - - def load_state_dict(self, state_dict, strict=False): - calls.append(("load_state_dict", state_dict, strict)) - self.loaded = state_dict - return [], [] - - def eval(self): - calls.append(("eval",)) - return self - - def to(self, device): - calls.append(("to", device)) - self.to_device = device - return self - - transformers.DetrImageProcessor = FakeProcessor - transformers.TableTransformerConfig = FakeConfig - transformers.TableTransformerForObjectDetection = FakeModel - monkeypatch.setitem(sys.modules, "transformers", transformers) - return FakeModel - - -def _install_fake_safetensors(monkeypatch, calls): - safetensors = types.ModuleType("safetensors") - safetensors_torch = types.ModuleType("safetensors.torch") - - def load_file(path, device="cpu"): - calls.append(("load_safetensors", str(path), device)) - return {"weight": "from-safetensors"} - - safetensors_torch.load_file = load_file - monkeypatch.setitem(sys.modules, "safetensors", safetensors) - monkeypatch.setitem(sys.modules, "safetensors.torch", safetensors_torch) - - -def test_table_transformer_loader_uses_config_state_dict_and_npu(monkeypatch, tmp_path): - process = _load_process_module() - calls = [] - model_cls = _install_fake_transformers(monkeypatch, calls) - _install_fake_safetensors(monkeypatch, calls) - (tmp_path / "model.safetensors").write_text("fake", encoding="utf-8") - - feature_extractor, model = process._load_local_table_transformer_model(tmp_path, "npu:0") - - assert feature_extractor is not None - assert isinstance(model, model_cls) - assert ("config", str(tmp_path), True) in calls - assert ("model_init", False) in calls - assert ("load_safetensors", str(tmp_path / "model.safetensors"), "cpu") in calls - assert ("load_state_dict", {"weight": "from-safetensors"}, False) in calls - assert ("to", "npu:0") in calls - assert model.to_device == "npu:0" - - -def test_pdf_runtime_overrides_initializes_table_agent_on_npu(monkeypatch, tmp_path): - process = _load_process_module() - calls = [] - _install_fake_transformers(monkeypatch, calls) - - unstructured_inference = types.ModuleType("unstructured_inference") - models_module = types.ModuleType("unstructured_inference.models") - tables_module = types.ModuleType("unstructured_inference.models.tables") - - class FakeTableAgent: - model = None - - class FakeTableTransformerModel: - initialize = lambda self, model=None, device="cpu": None - - tables_module.DEFAULT_MODEL = "old-model" - tables_module.tables_agent = FakeTableAgent() - tables_module.UnstructuredTableTransformerModel = FakeTableTransformerModel - tables_module.load_agent = lambda: None - models_module.tables = tables_module - unstructured_inference.models = models_module - monkeypatch.setitem(sys.modules, "unstructured_inference", unstructured_inference) - monkeypatch.setitem(sys.modules, "unstructured_inference.models", models_module) - monkeypatch.setitem(sys.modules, "unstructured_inference.models.tables", tables_module) - monkeypatch.setattr(process, "PDF_TABLE_MODEL_PATH", str(tmp_path)) - monkeypatch.setattr(process, "_select_table_transformer_device", lambda: "npu:0") - - def fake_loader(model_path, device): - calls.append(("loader", str(model_path), device)) - return "feature-extractor", "table-model" - - monkeypatch.setattr(process, "_load_local_table_transformer_model", fake_loader, raising=False) - - with process._pdf_runtime_overrides(): - tables_module.load_agent() - - assert ("loader", str(tmp_path), "npu:0") in calls - assert tables_module.tables_agent.device == "npu:0" - assert tables_module.tables_agent.feature_extractor == "feature-extractor" - assert tables_module.tables_agent.model == "table-model" - - -def test_pdf_runtime_overrides_rejects_cpu_table_device_in_strict_mode(monkeypatch, tmp_path): - process = _load_process_module() - - unstructured_inference = types.ModuleType("unstructured_inference") - models_module = types.ModuleType("unstructured_inference.models") - tables_module = types.ModuleType("unstructured_inference.models.tables") - - class FakeTableAgent: - model = None - - class FakeTableTransformerModel: - initialize = lambda self, model=None, device="cpu": None - - tables_module.DEFAULT_MODEL = "old-model" - tables_module.tables_agent = FakeTableAgent() - tables_module.UnstructuredTableTransformerModel = FakeTableTransformerModel - tables_module.load_agent = lambda: None - models_module.tables = tables_module - unstructured_inference.models = models_module - monkeypatch.setitem(sys.modules, "unstructured_inference", unstructured_inference) - monkeypatch.setitem(sys.modules, "unstructured_inference.models", models_module) - monkeypatch.setitem(sys.modules, "unstructured_inference.models.tables", tables_module) - monkeypatch.setattr(process, "PDF_TABLE_MODEL_PATH", str(tmp_path)) - monkeypatch.setattr(process, "_select_table_transformer_device", lambda: "cpu") - monkeypatch.setenv("UNSTRUCTUREDIO_REQUIRE_NPU_MODELS", "1") - - with process._pdf_runtime_overrides(): - try: - tables_module.load_agent() - except RuntimeError as exc: - assert "Table transformer NPU is required" in str(exc) - else: - raise AssertionError("strict mode accepted CPU table transformer device") From f38416e7a1af6e86a334937a417612ad4862067c Mon Sep 17 00:00:00 2001 From: qianqiuer <3418979384@qq.com> Date: Tue, 2 Jun 2026 22:11:40 +0800 Subject: [PATCH 4/5] Document portable paths for Huizhi operators --- runtime/ops/mapper/data_quality_evaluator/README.md | 9 ++++++++- .../service_patch/data_synthesis_service/README.md | 7 +++++++ runtime/ops/mapper/data_synthesis/README.md | 10 +++++++++- .../ops/mapper/data_synthesis/service_image/README.md | 8 ++++++++ .../service_patch/data_synthesis_service/README.md | 7 +++++++ .../ops/mapper/unstructuredio/NPU_ENV_CHECK_REPORT.md | 6 +++--- runtime/ops/mapper/unstructuredio/README.md | 8 ++++++++ .../ops/mapper/unstructuredio/operator_src/README.md | 7 +++++++ .../ops/mapper/unstructuredio/operator_src/process.py | 1 - 9 files changed, 57 insertions(+), 6 deletions(-) diff --git a/runtime/ops/mapper/data_quality_evaluator/README.md b/runtime/ops/mapper/data_quality_evaluator/README.md index 74b29467..4631fb56 100644 --- a/runtime/ops/mapper/data_quality_evaluator/README.md +++ b/runtime/ops/mapper/data_quality_evaluator/README.md @@ -36,6 +36,13 @@ DATA_EVALUATOR_BACKEND=vllm 使用 `service_patch/data_synthesis_service/Dockerfile` 构建正式 NPU 服务时,默认已经使用 910b-jss 对标基础镜像和 `requirements.txt`。如要覆盖基础镜像,必须保证新镜像与 `quay.io/ascend/vllm-ascend:v0.18.0rc1` 的 CANN/Python/vLLM 版本一致。 +路径说明: + +- 仓库内 `operator_src/`、`service_patch/`、`test_cases/` 均按相对路径组织,迁移到其他机器后保持目录结构即可。 +- `serviceUrl` 默认值与数据合成一致,为 `http://data-synthesis-service:18080`,表示 Docker 网络服务名;可在 DataMate 算子参数中改为实际可访问地址。 +- `/model` 是独立服务容器内模型挂载点,不是主机固定路径;评估模型具体位置由 `DATA_EVALUATOR_MODEL_PATH` 或平台参数 `evaluatorModelPath` 覆盖。 +- Dockerfile 中的 `/tmp/requirements*.txt` 只是镜像构建阶段临时文件,不是运行时输入输出路径。 + ## 如何生成 DataMate 上传包 压缩 `operator_src/` 目录中的全部文件,生成 `data_quality_evaluator.zip` 后上传 DataMate。 @@ -57,4 +64,4 @@ DATA_EVALUATOR_BACKEND=vllm 3. 新建任务,上传 `test_cases/example_input/public_eval_cases.json`。 4. 算子参数使用 `targetDimensions=accuracy,relevance,safety,diversity,completeness` 和 `evaluatorBackend=vllm`。 5. 运行任务并下载输出 JSON。 -6. 按 `test_cases/README.md` 检查每条记录是否包含 5 个维度评分、理由和汇总信息。 \ No newline at end of file +6. 按 `test_cases/README.md` 检查每条记录是否包含 5 个维度评分、理由和汇总信息。 diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/README.md b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/README.md index 5a6e68be..07c125f4 100644 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/README.md +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/README.md @@ -42,3 +42,10 @@ Dockerfile 使用 `pip install --no-deps`。这是为了保留 `quay.io/ascend/v - `DATA_EVALUATOR_MODEL_PATH` 默认模型挂载点为容器内 `/model`。 + +路径说明: + +- `data_synthesis_service/` 与 `data_synthesis/` 是构建上下文中的相对源码目录。 +- `/model` 是服务容器内模型挂载点,不是主机固定路径;主机模型目录由 Docker `-v` 参数挂载。 +- `/tmp/requirements*.txt` 是 Dockerfile 构建阶段临时依赖文件路径。 +- `/usr/local/Ascend/...` 是 vLLM-Ascend 基础镜像和宿主机驱动的容器内标准路径;非标准镜像需要提供等价路径。 diff --git a/runtime/ops/mapper/data_synthesis/README.md b/runtime/ops/mapper/data_synthesis/README.md index 7d75e992..2746b915 100644 --- a/runtime/ops/mapper/data_synthesis/README.md +++ b/runtime/ops/mapper/data_synthesis/README.md @@ -74,6 +74,14 @@ docker run -d --name data-synthesis-service \ - `/model` 是容器内模型挂载点,不是主机固定路径。 - NPU 启动参数默认第 6 号 NPU。使用其他 NPU 时,同步替换 `--device /dev/davinciX`、`ASCEND_VISIBLE_DEVICES` 和 `ASCEND_RT_VISIBLE_DEVICES`。 +路径说明: + +- 仓库内 `operator_src/`、`service_patch/`、`service_image/`、`test_cases/` 均按相对路径组织,迁移到其他机器后保持目录结构即可。 +- `serviceUrl` 默认值 `http://data-synthesis-service:18080` 是 Docker 网络服务名,不是固定主机地址;可在 DataMate 算子参数中改为实际可访问地址。 +- `/model` 是独立服务容器内模型挂载点,实际主机模型目录用 `-v :/model:ro` 指定;模型具体位置由 `DATA_SYNTHESIS_MODEL_PATH` 覆盖。 +- `/usr/local/Ascend/...`、`/usr/local/bin/npu-smi`、`/usr/local/dcmi` 是 Ascend NPU 宿主机组件挂载路径;如果验收机器路径不同,需要按实际驱动安装位置调整 `docker run -v` 参数。 +- Dockerfile 中的 `/tmp/requirements*.txt` 只是镜像构建阶段临时文件,不是运行时输入输出路径。 + 检查服务: ```bash @@ -115,4 +123,4 @@ http://data-synthesis-service:18080 3. 新建任务,上传 `test_cases/example_input/` 下的文本样例。 4. 算子参数 `taskTypes` 使用 `QA,CoT,Preference`。 5. 运行任务并下载输出 JSON。 -6. 按 `test_cases/README.md` 检查三类结果是否存在、字段是否完整,且结果由模型生成,失败时不会伪装为成功。 \ No newline at end of file +6. 按 `test_cases/README.md` 检查三类结果是否存在、字段是否完整,且结果由模型生成,失败时不会伪装为成功。 diff --git a/runtime/ops/mapper/data_synthesis/service_image/README.md b/runtime/ops/mapper/data_synthesis/service_image/README.md index c3a9505b..ab7f7b3a 100644 --- a/runtime/ops/mapper/data_synthesis/service_image/README.md +++ b/runtime/ops/mapper/data_synthesis/service_image/README.md @@ -60,6 +60,14 @@ docker run -d --name data-synthesis-service \ - 上例对标 910b-jss 第 6 号 NPU;如使用其他 NPU,需要同步调整 `--device /dev/davinciX`、`ASCEND_VISIBLE_DEVICES` 和 `ASCEND_RT_VISIBLE_DEVICES`。 - Ascend driver、`npu-smi`、`dcmi` 挂载项对标 910b-jss 的已验证启动方式,正式 NPU 推理不要省略。 +路径说明: + +- 本目录下的 Dockerfile、README 均使用相对构建上下文,迁移机器后保持 `service_patch/` 与 `service_image/` 的目录结构即可。 +- `/model` 是服务容器内模型挂载点,不是主机固定路径;主机模型目录由 `-v :/model:ro` 指定。 +- `/usr/local/Ascend/...`、`/usr/local/bin/npu-smi`、`/usr/local/dcmi` 是宿主机 Ascend 驱动组件路径;如果验收机器安装路径不同,需要按实际位置调整挂载参数。 +- `/tmp/requirements*.txt` 只在镜像构建阶段临时使用,不是运行时数据路径。 +- DataMate 算子访问服务时默认使用 Docker 网络名 `http://data-synthesis-service:18080`;实际服务名或端口不同时,通过算子参数 `serviceUrl` 覆盖。 + ## 健康检查 ```bash diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/README.md b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/README.md index 398fa439..65d1f771 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/README.md +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/README.md @@ -42,3 +42,10 @@ Dockerfile 使用 `pip install --no-deps`。这是为了保留 `quay.io/ascend/v - `DATA_EVALUATOR_MODEL_PATH` 默认模型挂载点为容器内 `/model`。 + +路径说明: + +- `data_synthesis_service/` 与 `data_synthesis/` 是构建上下文中的相对源码目录。 +- `/model` 是服务容器内模型挂载点,不是主机固定路径;主机模型目录由 Docker `-v` 参数挂载。 +- `/tmp/requirements*.txt` 是 Dockerfile 构建阶段临时依赖文件路径。 +- `/usr/local/Ascend/...` 是 vLLM-Ascend 基础镜像和宿主机驱动的容器内标准路径;非标准镜像需要提供等价路径。 diff --git a/runtime/ops/mapper/unstructuredio/NPU_ENV_CHECK_REPORT.md b/runtime/ops/mapper/unstructuredio/NPU_ENV_CHECK_REPORT.md index ad8b0236..27c4bb07 100644 --- a/runtime/ops/mapper/unstructuredio/NPU_ENV_CHECK_REPORT.md +++ b/runtime/ops/mapper/unstructuredio/NPU_ENV_CHECK_REPORT.md @@ -4,15 +4,15 @@ - 服务器:910b-jss - 测试容器:huizhi -- 测试目录:/home/o_pengjunjie/huizhi +- 测试目录:临时工作目录,非交付固定路径。 - NPU 选择:ASCEND_RT_VISIBLE_DEVICES=6 ## 已验证通过 - Torch-NPU 可用:`torch_npu==2.7.1` 可正常 import。 - Torch NPU 设备可用:`torch.npu.is_available()` 返回 True。 -- YOLOX PT 版面模型文件存在:`/home/o_pengjunjie/huizhi/unstructuredio_models/yolox_l.pt`。 -- YOLOX 源码目录存在:`/home/o_pengjunjie/huizhi/unstructuredio_models/YOLOX-main`。 +- YOLOX PT 版面模型文件已按 README 约定挂载,并可通过 `UNSTRUCTUREDIO_YOLOX_MODEL_PATH` 覆盖。 +- YOLOX 源码目录已按 README 约定挂载,并可通过 `UNSTRUCTUREDIO_YOLOX_SRC_PATH` 覆盖。 - PaddleOCR 本地模型目录存在:det、rec、cls 三类模型均已放置。 - `check_npu_runtime.py` 已采用子进程隔离检查 Torch-NPU 与 Paddle-NPU,并注入 Ascend/NNAL 动态库路径,避免同进程冲突和库路径误判。`process.py` 主进程和 `ocr_npu_adapter.py` worker 也已统一注入 Ascend/NNAL 动态库路径。 diff --git a/runtime/ops/mapper/unstructuredio/README.md b/runtime/ops/mapper/unstructuredio/README.md index c5e64583..8982f0bc 100644 --- a/runtime/ops/mapper/unstructuredio/README.md +++ b/runtime/ops/mapper/unstructuredio/README.md @@ -37,6 +37,14 @@ - `UNSTRUCTUREDIO_OCR_CLS_MODEL_DIR=/models/unstructuredio/paddleocr/ch_ppocr_mobile_v2.0_cls_infer` - `UNSTRUCTUREDIO_TABLE_MODEL_PATH=/models/unstructuredio/table-transformer-structure-recognition` +路径说明: + +- `operator_src/`、`test_cases/` 等仓库内目录均使用相对路径说明,迁移到其他机器后保持目录结构即可。 +- `/models`、`/model` 是容器内模型挂载点,不是主机固定路径。验收方可把主机任意模型目录挂载到该容器内路径,或通过上述环境变量改成其他容器内路径。 +- `/tmp` 仅用于运行时临时文件和 Paddle CPU 隔离目录,不承载交付数据;如运行环境限制 `/tmp`,可通过 `TMPDIR` 或 `OCR_ADAPTER_CPU_CUSTOM_DEVICE_ROOT` 调整。 +- `/usr/local/Ascend/...` 是 Ascend 驱动、CANN、NNAL 的容器内标准库路径;如镜像路径不同,应先通过容器挂载或 `LD_LIBRARY_PATH` 提供等价路径。 +- `HF_ENDPOINT` 默认指向 `https://hf-mirror.com`,只用于拦截/镜像 HuggingFace 请求;正式验收建议本地预置模型,避免运行时访问外网。 + 表格结构模型不存在时,算子会关闭 `infer_table_structure`,避免运行时访问远程模型;PDF 表格标题仍会做轻量补强和合并。 ## NPU 运行依赖 diff --git a/runtime/ops/mapper/unstructuredio/operator_src/README.md b/runtime/ops/mapper/unstructuredio/operator_src/README.md index f0224964..528c4326 100644 --- a/runtime/ops/mapper/unstructuredio/operator_src/README.md +++ b/runtime/ops/mapper/unstructuredio/operator_src/README.md @@ -35,6 +35,13 @@ - `UNSTRUCTUREDIO_OCR_CLS_MODEL_DIR`:默认 `/models/unstructuredio/paddleocr/ch_ppocr_mobile_v2.0_cls_infer`。 - `UNSTRUCTUREDIO_TABLE_MODEL_PATH`:默认 `/models/unstructuredio/table-transformer-structure-recognition`。 +路径说明: + +- 默认模型路径均为容器内路径,不绑定任何主机目录;迁移机器时只需要把主机模型目录挂载到容器内 `/models` 或 `/model`,或通过环境变量覆盖。 +- `adapters/YOLOX-main` 和 `operator_src/YOLOX-main` 是算子内相对候选路径;如果不随算子携带 YOLOX 源码,应设置 `UNSTRUCTUREDIO_YOLOX_SRC_PATH`。 +- `/tmp` 仅用于临时 JSON、临时输出和 Paddle CPU 隔离目录;可通过系统 `TMPDIR` 或 `OCR_ADAPTER_CPU_CUSTOM_DEVICE_ROOT` 覆盖。 +- Ascend 相关 `/usr/local/Ascend/...` 是容器内标准库路径;非标准镜像需要通过挂载或 `LD_LIBRARY_PATH` 提供等价路径。 + 表格结构模型不存在时会关闭 `infer_table_structure`,避免访问远程模型。 ## 验证 diff --git a/runtime/ops/mapper/unstructuredio/operator_src/process.py b/runtime/ops/mapper/unstructuredio/operator_src/process.py index f8652da9..21366b0d 100644 --- a/runtime/ops/mapper/unstructuredio/operator_src/process.py +++ b/runtime/ops/mapper/unstructuredio/operator_src/process.py @@ -40,7 +40,6 @@ def _configure_nltk_import_environment() -> None: os.getenv("UNSTRUCTUREDIO_NLTK_DATA", ""), "/models/unstructuredio/nltk_data", "/model/unstructuredio/nltk_data", - "/home/o_pengjunjie/huizhi/unstructuredio_models/nltk_data", ] for preferred in preferred_paths: if preferred and Path(preferred).exists() and not _nltk_path_has_bad_zip(preferred): From 2bf056f83c17935d7e4d4b8e76f241280a8a04a0 Mon Sep 17 00:00:00 2001 From: qianqiuer <3418979384@qq.com> Date: Tue, 9 Jun 2026 16:35:20 +0800 Subject: [PATCH 5/5] Finalize Huizhi operator deliveries --- .../mapper/data_quality_evaluator/README.md | 67 - .../example_input/data_quality_eval_demo.json | 28 - .../operator_src/README.md | 22 +- .../operator_src/metadata.yml | 6 +- .../operator_src/process.py | 36 +- .../operator_src/requirements.txt | 4 +- .../data_evaluator.py | 9 +- .../data_quality_evaluator_service/README.md | 36 + .../__init__.py | 1 + .../app.py | 49 +- .../data_quality_evaluator_service/core.py | 387 +++++ .../requirements.txt | 25 + .../tests/test_app.py | 63 +- .../tests/test_core.py | 73 + .../data_synthesis/data_synthesizer.py | 1337 --------------- .../data_synthesis/requirement_metrics.py | 83 - .../data_synthesis/test_evaluator_backend.py | 110 -- .../data_synthesis_service/Dockerfile | 18 - .../data_synthesis_service/README.md | 51 - .../data_synthesis_service/__init__.py | 4 - .../data_synthesis_service/core.py | 607 ------- .../requirements-base.txt | 7 - .../requirements-npu.txt | 2 - .../data_synthesis_service/requirements.txt | 20 - .../tests/test_evaluator_backend_service.py | 76 - .../test_cases/README.md | 64 +- .../test_cases/cases.json | 667 +++++++- .../test_cases/example_input/dq_case_01.json | 12 + .../test_cases/example_input/dq_case_02.json | 12 + .../test_cases/example_input/dq_case_03.json | 13 + .../test_cases/example_input/dq_case_04.json | 14 + .../test_cases/example_input/dq_case_05.json | 12 + .../test_cases/example_input/dq_case_06.json | 12 + .../test_cases/example_input/dq_case_07.json | 12 + .../test_cases/example_input/dq_case_08.json | 12 + .../test_cases/example_input/dq_case_09.json | 13 + .../test_cases/example_input/dq_case_10.json | 14 + .../test_cases/example_input/dq_case_11.json | 12 + .../test_cases/example_input/dq_case_12.json | 12 + .../test_cases/example_input/dq_case_13.json | 12 + .../test_cases/example_input/dq_case_14.json | 12 + .../test_cases/example_input/dq_case_15.json | 13 + .../test_cases/example_input/dq_case_16.json | 14 + .../test_cases/example_input/dq_case_17.json | 12 + .../test_cases/example_input/dq_case_18.json | 12 + .../test_cases/example_input/dq_case_19.json | 12 + .../test_cases/example_input/dq_case_20.json | 12 + .../test_cases/example_input/dq_case_21.json | 13 + .../test_cases/example_input/dq_case_22.json | 14 + .../test_cases/example_input/dq_case_23.json | 12 + .../test_cases/example_input/dq_case_24.json | 12 + .../test_cases/example_input/dq_case_25.json | 12 + .../test_cases/example_input/dq_case_26.json | 12 + .../test_cases/example_input/dq_case_27.json | 13 + .../test_cases/example_input/dq_case_28.json | 14 + .../test_cases/example_input/dq_case_29.json | 12 + .../test_cases/example_input/dq_case_30.json | 12 + .../example_input/public_eval_cases.json | 14 +- runtime/ops/mapper/data_synthesis/README.md | 131 +- .../example_input/data_synthesis_demo.txt | 1 - .../data_synthesis/operator_src/README.md | 25 +- .../data_synthesis/operator_src/metadata.yml | 28 +- .../data_synthesis/operator_src/process.py | 162 +- .../operator_src/requirements.txt | 4 +- .../data_synthesis/service_image/Dockerfile | 6 +- .../data_synthesis/service_image/README.md | 78 +- .../service_patch/data_synthesis/README.md | 41 +- .../data_synthesis/benchmark_and_visualize.py | 6 +- .../data_synthesis/data_evaluator.py | 2 +- .../data_synthesis/data_synthesizer.py | 1495 +++++++++++++++-- .../data_synthesis/final_delivery_part1.py | 6 +- .../data_synthesis/prepare_golden_data.py | 4 +- .../data_synthesis/run_50_each_test.py | 4 +- ...test_acute_stroke_preference_regression.py | 37 + .../test_generation_quality_regressions.py | 61 + .../test_medication_safety_cleanup.py | 320 ++++ .../test_project_requirements.py | 427 ++++- .../test_qa_fast_path_regressions.py | 144 ++ .../test_qa_mixed_payload_regressions.py | 160 ++ ...test_qa_public_case_quality_regressions.py | 66 + .../data_synthesis/test_qa_repair_budget.py | 136 ++ .../test_review_regeneration.py | 110 ++ .../data_synthesis_service/Dockerfile | 9 +- .../data_synthesis_service/README.md | 44 +- .../data_synthesis_service/app.py | 40 +- .../data_synthesis_service/core.py | 488 ++---- .../requirements-base.txt | 7 - .../requirements-npu.txt | 2 - .../data_synthesis_service/requirements.txt | 36 +- .../data_synthesis_service/tests/test_app.py | 73 +- .../tests/test_evaluator_backend_service.py | 13 +- .../tests/test_operator_process.py | 112 +- .../tests/test_service_core.py | 316 ++-- .../data_synthesis/test_cases/README.md | 60 +- .../data_synthesis/test_cases/cases.json | 642 ++++++- .../example_input/cmedqa2_style_case_cn.txt | 7 - .../test_cases/example_input/ds_case_01.txt | 6 + .../test_cases/example_input/ds_case_02.txt | 6 + .../test_cases/example_input/ds_case_03.txt | 6 + .../test_cases/example_input/ds_case_04.txt | 6 + .../test_cases/example_input/ds_case_05.txt | 6 + .../test_cases/example_input/ds_case_06.txt | 6 + .../test_cases/example_input/ds_case_07.txt | 6 + .../test_cases/example_input/ds_case_08.txt | 6 + .../test_cases/example_input/ds_case_09.txt | 6 + .../test_cases/example_input/ds_case_10.txt | 6 + .../test_cases/example_input/ds_case_11.txt | 6 + .../test_cases/example_input/ds_case_12.txt | 6 + .../test_cases/example_input/ds_case_13.txt | 6 + .../test_cases/example_input/ds_case_14.txt | 6 + .../test_cases/example_input/ds_case_15.txt | 6 + .../test_cases/example_input/ds_case_16.txt | 6 + .../test_cases/example_input/ds_case_17.txt | 6 + .../test_cases/example_input/ds_case_18.txt | 6 + .../test_cases/example_input/ds_case_19.txt | 6 + .../test_cases/example_input/ds_case_20.txt | 6 + .../test_cases/example_input/ds_case_21.txt | 6 + .../test_cases/example_input/ds_case_22.txt | 6 + .../test_cases/example_input/ds_case_23.txt | 6 + .../test_cases/example_input/ds_case_24.txt | 6 + .../test_cases/example_input/ds_case_25.txt | 6 + .../test_cases/example_input/ds_case_26.txt | 6 + .../test_cases/example_input/ds_case_27.txt | 6 + .../test_cases/example_input/ds_case_28.txt | 6 + .../test_cases/example_input/ds_case_29.txt | 6 + .../test_cases/example_input/ds_case_30.txt | 6 + .../example_input/pubmedqa_style_case_en.txt | 10 - .../unstructuredio/NPU_ENV_CHECK_REPORT.md | 68 - runtime/ops/mapper/unstructuredio/README.md | 8 - .../unstructuredio/operator_src/README.md | 13 +- .../adapters/requirements_npu_v1.2_stable.txt | 8 +- .../unstructuredio/operator_src/process.py | 1 + .../operator_src/requirements.txt | 28 +- .../tests/test_check_npu_runtime.py | 65 + .../tests/test_npu_adapter_cpu_fallback.py | 31 + .../operator_src/tests/test_ocr_cpu_patch.py | 45 + .../tests/test_pdf_npu_ocr_priority.py | 390 +++++ .../tests/test_process_ascend_env.py | 27 + .../tests/test_require_npu_models.py | 229 +++ .../tests/test_table_transformer_npu.py | 162 ++ .../unstructuredio/test_cases/README.md | 66 +- .../unstructuredio/test_cases/cases.json | 117 +- 142 files changed, 7187 insertions(+), 3805 deletions(-) delete mode 100644 runtime/ops/mapper/data_quality_evaluator/README.md delete mode 100644 runtime/ops/mapper/data_quality_evaluator/example_input/data_quality_eval_demo.json rename runtime/ops/mapper/data_quality_evaluator/service_patch/{data_synthesis => data_quality_evaluator}/data_evaluator.py (98%) create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/README.md create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/__init__.py rename runtime/ops/mapper/data_quality_evaluator/service_patch/{data_synthesis_service => data_quality_evaluator_service}/app.py (56%) create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/core.py create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/requirements.txt rename runtime/ops/mapper/data_quality_evaluator/service_patch/{data_synthesis_service => data_quality_evaluator_service}/tests/test_app.py (50%) create mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/tests/test_core.py delete mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/data_synthesizer.py delete mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/requirement_metrics.py delete mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/test_evaluator_backend.py delete mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/Dockerfile delete mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/README.md delete mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/__init__.py delete mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/core.py delete mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements-base.txt delete mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements-npu.txt delete mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements.txt delete mode 100644 runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/tests/test_evaluator_backend_service.py create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_01.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_02.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_03.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_04.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_05.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_06.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_07.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_08.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_09.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_10.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_11.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_12.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_13.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_14.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_15.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_16.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_17.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_18.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_19.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_20.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_21.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_22.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_23.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_24.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_25.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_26.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_27.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_28.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_29.json create mode 100644 runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_30.json delete mode 100644 runtime/ops/mapper/data_synthesis/example_input/data_synthesis_demo.txt create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_acute_stroke_preference_regression.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_generation_quality_regressions.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_medication_safety_cleanup.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_qa_fast_path_regressions.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_qa_mixed_payload_regressions.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_qa_public_case_quality_regressions.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_qa_repair_budget.py create mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_review_regeneration.py delete mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements-base.txt delete mode 100644 runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements-npu.txt delete mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/cmedqa2_style_case_cn.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_01.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_02.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_03.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_04.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_05.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_06.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_07.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_08.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_09.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_10.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_11.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_12.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_13.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_14.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_15.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_16.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_17.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_18.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_19.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_20.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_21.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_22.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_23.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_24.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_25.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_26.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_27.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_28.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_29.txt create mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_30.txt delete mode 100644 runtime/ops/mapper/data_synthesis/test_cases/example_input/pubmedqa_style_case_en.txt delete mode 100644 runtime/ops/mapper/unstructuredio/NPU_ENV_CHECK_REPORT.md create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_check_npu_runtime.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_npu_adapter_cpu_fallback.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_ocr_cpu_patch.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_pdf_npu_ocr_priority.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_process_ascend_env.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_require_npu_models.py create mode 100644 runtime/ops/mapper/unstructuredio/operator_src/tests/test_table_transformer_npu.py diff --git a/runtime/ops/mapper/data_quality_evaluator/README.md b/runtime/ops/mapper/data_quality_evaluator/README.md deleted file mode 100644 index 4631fb56..00000000 --- a/runtime/ops/mapper/data_quality_evaluator/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# data\_quality\_evaluator 算子 - -目录内容 - -- `operator_src/` DataMate 平台轻量算子源码。 -- `service_patch/` 独立服务端评估接口相关代码。 -- `example_input/` 手工联调输入样例。 -- `test_cases/` 公开数据集来源说明、轻量评估样例和测试步骤。 - -## 开源模型链接 - -- 评估模型 `Qwen/Qwen2.5-7B-Instruct`: [https://huggingface.co/Qwen/Qwen2.5-7B-Instruct](https://huggingface.co/Qwen/Qwen2.5-7B-Instruct "https://huggingface.co/Qwen/Qwen2.5-7B-Instruct") - -说明:数据质量评估使用 `Qwen2.5-7B-Instruct`。 - -## 独立服务部署 - -数据质量评估算子复用 `data_synthesis_service` 独立服务,但调用的是 `/evaluate-file` 接口。 - -依赖说明: - -- `operator_src/requirements.txt` 是 DataMate 轻量算子依赖,只包含 HTTP 调用所需依赖,不包含 `vllm`。 -- `service_patch/data_synthesis_service/requirements.txt` 是独立服务生产依赖。 -- 服务基础镜像固定为 `quay.io/ascend/vllm-ascend:v0.18.0rc1`,对应 Python `3.11.14`、CANN `8.5.1`。 -- 关键版本包括 `vllm==0.18.0+empty`、`vllm_ascend==0.18.0rc1`、`torch==2.9.0+cpu`、`torch_npu==2.9.0.post1+gitee7ba04`。 -- `service_patch/data_synthesis_service/requirements-base.txt` 只用于无模型的接口冒烟测试,不用于正式验收推理。 - -推荐模型环境变量: - -```bash -DATA_EVALUATOR_MODEL_PATH=/model/Qwen/Qwen2.5-7B-Instruct -DATA_EVALUATOR_BACKEND=vllm -``` - -`/model` 是容器内模型挂载点。验收方可把本机任意模型目录挂载到容器内 `/model`,或在平台参数 `evaluatorModelPath` 中改为其他容器内路径。 - -使用 `service_patch/data_synthesis_service/Dockerfile` 构建正式 NPU 服务时,默认已经使用 910b-jss 对标基础镜像和 `requirements.txt`。如要覆盖基础镜像,必须保证新镜像与 `quay.io/ascend/vllm-ascend:v0.18.0rc1` 的 CANN/Python/vLLM 版本一致。 - -路径说明: - -- 仓库内 `operator_src/`、`service_patch/`、`test_cases/` 均按相对路径组织,迁移到其他机器后保持目录结构即可。 -- `serviceUrl` 默认值与数据合成一致,为 `http://data-synthesis-service:18080`,表示 Docker 网络服务名;可在 DataMate 算子参数中改为实际可访问地址。 -- `/model` 是独立服务容器内模型挂载点,不是主机固定路径;评估模型具体位置由 `DATA_EVALUATOR_MODEL_PATH` 或平台参数 `evaluatorModelPath` 覆盖。 -- Dockerfile 中的 `/tmp/requirements*.txt` 只是镜像构建阶段临时文件,不是运行时输入输出路径。 - -## 如何生成 DataMate 上传包 - -压缩 `operator_src/` 目录中的全部文件,生成 `data_quality_evaluator.zip` 后上传 DataMate。 - -压缩包根目录应直接包含: - -- `metadata.yml` -- `process.py` -- `__init__.py` -- `requirements.txt` -- `README.md` - -`service_patch/`、`example_input/`、`test_cases/` 只用于服务部署和验收测试,不放入 DataMate 算子上传包。 - -## 平台测试 - -1. 启动带评估接口的独立服务,并确保 DataMate 运行环境能访问 `serviceUrl`。 -2. 在 DataMate 算子市场上传按上述规则生成的上传包。 -3. 新建任务,上传 `test_cases/example_input/public_eval_cases.json`。 -4. 算子参数使用 `targetDimensions=accuracy,relevance,safety,diversity,completeness` 和 `evaluatorBackend=vllm`。 -5. 运行任务并下载输出 JSON。 -6. 按 `test_cases/README.md` 检查每条记录是否包含 5 个维度评分、理由和汇总信息。 diff --git a/runtime/ops/mapper/data_quality_evaluator/example_input/data_quality_eval_demo.json b/runtime/ops/mapper/data_quality_evaluator/example_input/data_quality_eval_demo.json deleted file mode 100644 index c36576fb..00000000 --- a/runtime/ops/mapper/data_quality_evaluator/example_input/data_quality_eval_demo.json +++ /dev/null @@ -1,28 +0,0 @@ -[ - { - "id": 1, - "type": "QA", - "content": { - "question": "青霉素过敏患者还能继续使用阿莫西林吗?", - "answer": "可以继续使用阿莫西林,无需担心过敏。" - } - }, - { - "id": 2, - "type": "QA", - "content": { - "question": "高血压患者日常应如何进行家庭血压监测?", - "answer": "建议固定时间测量血压,记录结果,低盐饮食,规律运动,并按医嘱服药。" - } - }, - { - "id": 3, - "type": "Preference", - "content": { - "question": "高血压患者日常应如何进行家庭血压监测?", - "chosen": "建议每天在固定时间测量血压,连续记录,配合低盐饮食、体重管理和按医嘱复诊。", - "rejected": "血压偶尔量一下就可以,不需要长期记录。", - "preference_reason": "chosen 方案更完整,更符合长期慢病管理要求。" - } - } -] diff --git a/runtime/ops/mapper/data_quality_evaluator/operator_src/README.md b/runtime/ops/mapper/data_quality_evaluator/operator_src/README.md index 4c968cfc..a41bcbb6 100644 --- a/runtime/ops/mapper/data_quality_evaluator/operator_src/README.md +++ b/runtime/ops/mapper/data_quality_evaluator/operator_src/README.md @@ -1,21 +1,3 @@ -# data_quality_evaluator 算子源码 +# data_quality_evaluator -本目录是 DataMate 平台上传包中的算子源码。 - -## 功能 - -- 读取平台传入的一个输入文件。 -- 将文件内容作为待评估 JSON 文本。 -- 调用独立服务的 `/evaluate-file` 接口。 -- 将服务返回的评估结果写成平台输出 JSON 文件。 - -## 关键参数 - -- `serviceUrl` - 独立服务 HTTP 地址,默认使用容器网络服务名 `http://data-synthesis-service:18080`。 -- `targetDimensions` - 评估维度,默认 `accuracy,relevance,safety,diversity,completeness`。 -- `evaluatorBackend` - 评估后端,默认 `vllm`。 -- `evaluatorModelPath` - 评估模型在服务容器内的路径。 +DataMate mapper operator for calling the standalone `data_quality_evaluator` service and exporting one JSON result file. diff --git a/runtime/ops/mapper/data_quality_evaluator/operator_src/metadata.yml b/runtime/ops/mapper/data_quality_evaluator/operator_src/metadata.yml index 13e873d6..86a105ad 100644 --- a/runtime/ops/mapper/data_quality_evaluator/operator_src/metadata.yml +++ b/runtime/ops/mapper/data_quality_evaluator/operator_src/metadata.yml @@ -1,5 +1,5 @@ name: 'data_quality_evaluator' -description: 'Call the standalone data_synthesis HTTP service to evaluate generated data quality and export one JSON result file.' +description: 'Call the standalone data_quality_evaluator HTTP service to evaluate generated data quality and export one JSON result file.' language: 'python' vendor: 'huawei' raw_id: 'DataQualityEvaluatorMapper' @@ -22,9 +22,9 @@ runtime: settings: serviceUrl: name: 'Service URL' - description: 'HTTP endpoint of the standalone data_synthesis service.' + description: 'HTTP endpoint of the standalone data_quality_evaluator service.' type: 'input' - defaultVal: 'http://data-synthesis-service:18080' + defaultVal: 'http://data-quality-evaluator-service:18112' required: true targetDimensions: name: 'Target Dimensions' diff --git a/runtime/ops/mapper/data_quality_evaluator/operator_src/process.py b/runtime/ops/mapper/data_quality_evaluator/operator_src/process.py index acf54143..830f2e85 100644 --- a/runtime/ops/mapper/data_quality_evaluator/operator_src/process.py +++ b/runtime/ops/mapper/data_quality_evaluator/operator_src/process.py @@ -15,21 +15,32 @@ def __init__(self, *args, **kwargs): self.target_type_key = kwargs.get("target_type_key", "target_type") -DEFAULT_SERVICE_URL = "http://data-synthesis-service:18080" +DEFAULT_SERVICE_URL = "http://data-quality-evaluator-service:18112" DEFAULT_EVALUATOR_MODEL_PATH = "/model/Qwen/Qwen2.5-7B-Instruct" +DIM_ACCURACY = "\u51c6\u786e\u6027" +DIM_RELEVANCE = "\u76f8\u5173\u6027" +DIM_SAFETY = "\u5b89\u5168\u6027" +DIM_DIVERSITY = "\u591a\u6837\u6027" +DIM_COMPLETENESS = "\u5b8c\u6574\u6027" DIMENSION_ALIASES = { - "accuracy": "准确性", - "relevance": "相关性", - "safety": "安全性", - "diversity": "多样性", - "completeness": "完整性", - "准确性": "准确性", - "相关性": "相关性", - "安全性": "安全性", - "多样性": "多样性", - "完整性": "完整性", + "accuracy": DIM_ACCURACY, + "relevance": DIM_RELEVANCE, + "safety": DIM_SAFETY, + "diversity": DIM_DIVERSITY, + "completeness": DIM_COMPLETENESS, + DIM_ACCURACY: DIM_ACCURACY, + DIM_RELEVANCE: DIM_RELEVANCE, + DIM_SAFETY: DIM_SAFETY, + DIM_DIVERSITY: DIM_DIVERSITY, + DIM_COMPLETENESS: DIM_COMPLETENESS, } -DEFAULT_DIMENSIONS = ["准确性", "相关性", "安全性", "多样性", "完整性"] +DEFAULT_DIMENSIONS = [ + DIM_ACCURACY, + DIM_RELEVANCE, + DIM_SAFETY, + DIM_DIVERSITY, + DIM_COMPLETENESS, +] def _parse_dimensions(value: Any) -> List[str]: @@ -40,7 +51,6 @@ def _parse_dimensions(value: Any) -> List[str]: else: items = [str(item).strip() for item in value if str(item).strip()] - # DataMate may garble non-ASCII operator params into question marks. if items and all(set(item) <= {"?"} for item in items): return list(DEFAULT_DIMENSIONS) diff --git a/runtime/ops/mapper/data_quality_evaluator/operator_src/requirements.txt b/runtime/ops/mapper/data_quality_evaluator/operator_src/requirements.txt index f2293605..ee509365 100644 --- a/runtime/ops/mapper/data_quality_evaluator/operator_src/requirements.txt +++ b/runtime/ops/mapper/data_quality_evaluator/operator_src/requirements.txt @@ -1 +1,3 @@ -requests +# DataMate operator wrapper dependencies. +# Heavy model runtime dependencies are provided by the standalone service. +requests==2.32.5 diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/data_evaluator.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator/data_evaluator.py similarity index 98% rename from runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/data_evaluator.py rename to runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator/data_evaluator.py index dbf66cb6..7fe2d533 100644 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/data_evaluator.py +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator/data_evaluator.py @@ -34,7 +34,12 @@ def __init__( ): # 规则优先:在二值评估场景下先用可解释规则,必要时再回退到 LLM self.model_path = model_path - self.backend = (backend or os.environ.get("DATA_EVALUATOR_BACKEND") or "rule").strip().lower() + self.backend = ( + backend + or os.environ.get("DATA_QUALITY_EVALUATOR_BACKEND") + or os.environ.get("DATA_EVALUATOR_BACKEND") + or "rule" + ).strip().lower() if self.backend not in {"rule", "vllm"}: raise ValueError(f"Unsupported evaluator backend: {self.backend}") self.enable_rule_based = self.backend == "rule" @@ -353,7 +358,7 @@ def evaluate(self, data_list: List[Dict[str, Any]], target_dimensions: Optional[ prompts.append(prompt) task_mapping.append((i, dim)) - print(f"🚀 [Evaluator] 开始批量打分: {len(data_list)} 条数据 x {len(target_dimensions)} 维度 = {len(prompts)} 次推理") + print(f"[Evaluator] 开始批量打分: {len(data_list)} 条数据 x {len(target_dimensions)} 维度 = {len(prompts)} 次推理") # 2. 执行推理 (Low Temperature for consistency) sampling_params = SamplingParams( diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/README.md b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/README.md new file mode 100644 index 00000000..b2d874ca --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/README.md @@ -0,0 +1,36 @@ +# data_quality_evaluator_service 独立服务 + +该目录是数据质量评估算子的独立 FastAPI 服务代码,只提供质量评估能力。 + +## 接口 + +- `GET /health` +- `POST /evaluate-file` + +## 启动 + +```bash +python -m uvicorn data_quality_evaluator_service.app:app --host 0.0.0.0 --port 18112 +``` + +正式容器建议使用 `data-quality-evaluator-service` 作为容器名,并加入 DataMate 所在 Docker 网络。DataMate 算子默认访问: + +```text +http://data-quality-evaluator-service:18112 +``` + +## 依赖 + +`requirements.txt` 对标已验证的 Ascend/vLLM 环境;DataMate 算子本体不安装 vLLM,只通过 HTTP 调用该独立服务。 + +## 模型路径 + +通过环境变量指定模型路径: + +- `DATA_QUALITY_EVALUATOR_MODEL_PATH`:数据质量评估模型,默认 `/model/Qwen/Qwen2.5-7B-Instruct`。 + +容器内建议设置: + +```bash +export no_proxy="localhost,127.0.0.1,data-quality-evaluator-service" +``` diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/__init__.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/__init__.py new file mode 100644 index 00000000..482cea32 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/__init__.py @@ -0,0 +1 @@ +"""Standalone HTTP service for the data_quality_evaluator operator.""" diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/app.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/app.py similarity index 56% rename from runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/app.py rename to runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/app.py index b502c8ff..e662ddb1 100644 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/app.py +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/app.py @@ -1,22 +1,17 @@ +import os +from contextlib import asynccontextmanager from typing import List, Optional from fastapi import FastAPI, HTTPException from pydantic import BaseModel, Field -from .core import SynthesisService +from .core import DataQualityEvaluatorService class HealthRequest(BaseModel): pass -class SynthesizeFileRequest(BaseModel): - file_name: str = Field(..., min_length=1) - text: str = Field(..., min_length=1) - task_types: Optional[List[str]] = None - include_metrics: bool = True - - class EvaluateFileRequest(BaseModel): file_name: str = Field(..., min_length=1) text: str = Field(..., min_length=1) @@ -26,9 +21,25 @@ class EvaluateFileRequest(BaseModel): backend: Optional[str] = None -def create_app(service: Optional[SynthesisService] = None) -> FastAPI: - app = FastAPI(title="data_synthesis_service", version="1.0.0") - active_service = service or SynthesisService() +def _skip_warmup() -> bool: + return str(os.environ.get("DATA_QUALITY_EVALUATOR_SKIP_WARMUP", "")).strip().lower() in { + "1", + "true", + "yes", + "on", + } + + +def create_app(service: Optional[DataQualityEvaluatorService] = None) -> FastAPI: + active_service = service or DataQualityEvaluatorService() + + @asynccontextmanager + async def lifespan(_: FastAPI): + if not _skip_warmup(): + active_service.warmup() + yield + + app = FastAPI(title="data_quality_evaluator_service", version="1.0.0", lifespan=lifespan) @app.get("/health") def health_get() -> dict: @@ -38,22 +49,6 @@ def health_get() -> dict: def health(_: HealthRequest) -> dict: return active_service.health() - @app.post("/synthesize-file") - def synthesize_file(request: SynthesizeFileRequest) -> dict: - try: - return active_service.synthesize_text( - file_name=request.file_name, - text=request.text, - task_types=request.task_types, - include_metrics=request.include_metrics, - ) - except ValueError as exc: - raise HTTPException(status_code=400, detail=str(exc)) from exc - except RuntimeError as exc: - raise HTTPException(status_code=503, detail=str(exc)) from exc - except Exception as exc: - raise HTTPException(status_code=500, detail=str(exc)) from exc - @app.post("/evaluate-file") def evaluate_file(request: EvaluateFileRequest) -> dict: try: diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/core.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/core.py new file mode 100644 index 00000000..b4fc21f9 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/core.py @@ -0,0 +1,387 @@ +import json +import os +import subprocess +import sys +import threading +from concurrent.futures import ThreadPoolExecutor +from typing import Any, Dict, Iterable, List, Optional + + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +PROJECT_ROOT = os.path.dirname(CURRENT_DIR) +DATA_QUALITY_EVALUATOR_DIR = os.path.join(PROJECT_ROOT, "data_quality_evaluator") +if DATA_QUALITY_EVALUATOR_DIR not in sys.path: + sys.path.insert(0, DATA_QUALITY_EVALUATOR_DIR) + +from data_evaluator import MedicalDataEvaluator + + +DEFAULT_EVALUATION_DIMENSIONS = ("准确性", "相关性", "安全性", "多样性", "完整性") +EVALUATION_DIMENSION_ALIASES = { + "accuracy": "准确性", + "relevance": "相关性", + "safety": "安全性", + "diversity": "多样性", + "completeness": "完整性", + "准确性": "准确性", + "相关性": "相关性", + "安全性": "安全性", + "多样性": "多样性", + "完整性": "完整性", +} +DEFAULT_EVALUATOR_MODEL_PATH = "/model/Qwen/Qwen2.5-7B-Instruct" +SERVICE_REQUEST_LOCK = threading.RLock() +WORKER_RESULT_PREFIX = "__DATA_QUALITY_EVALUATOR_RESULT__" + + +def _is_truthy_env(name: str) -> bool: + return str(os.environ.get(name, "")).strip().lower() in {"1", "true", "yes", "on"} + + +def _parse_worker_stdout(stdout: str) -> Dict[str, Any]: + output_lines = [line.strip() for line in stdout.splitlines() if line.strip()] + if not output_lines: + raise RuntimeError("subprocess returned empty output") + + for line in reversed(output_lines): + if line.startswith(WORKER_RESULT_PREFIX): + return json.loads(line[len(WORKER_RESULT_PREFIX):]) + + for line in reversed(output_lines): + if line.startswith("{") or line.startswith("["): + return json.loads(line) + + raise RuntimeError("subprocess returned no JSON result") + + +def _normalize_dimensions(target_dimensions: Optional[Iterable[str]]) -> List[str]: + if target_dimensions is None: + return list(DEFAULT_EVALUATION_DIMENSIONS) + raw_dimensions = [str(dim).strip() for dim in target_dimensions if str(dim).strip()] + normalized = [ + EVALUATION_DIMENSION_ALIASES.get(dim.lower(), EVALUATION_DIMENSION_ALIASES.get(dim)) + for dim in raw_dimensions + ] + invalid = [dim for dim, mapped in zip(raw_dimensions, normalized) if mapped is None] + if invalid: + raise ValueError(f"Unsupported target_dimensions: {invalid}") + if not normalized: + raise ValueError("target_dimensions must not be empty") + return [dim for dim in normalized if dim] + + +def _make_record(record_id: int, task_type: str, payload: Dict[str, Any]) -> Dict[str, Any]: + return { + "id": record_id, + "type": task_type, + "content": json.dumps(payload, ensure_ascii=False), + } + + +def _records_from_synthesis_payload(payload: Dict[str, Any]) -> List[Dict[str, Any]]: + records: List[Dict[str, Any]] = [] + next_id = 1 + results = payload.get("results", {}) + if not isinstance(results, dict): + return records + + for task_type in ("QA", "CoT", "Preference"): + items = results.get(task_type, []) + if not isinstance(items, list): + continue + for item in items: + data = item + if isinstance(item, dict) and "data" in item: + if item.get("status") != "success": + continue + data = item.get("data", {}) + if not isinstance(data, dict): + continue + records.append(_make_record(next_id, task_type, data)) + next_id += 1 + return records + + +def _parse_evaluation_input(text: str) -> List[Dict[str, Any]]: + raw = (text or "").strip() + if not raw: + raise ValueError("text must not be empty") + + try: + parsed = json.loads(raw) + except json.JSONDecodeError as exc: + raise ValueError("evaluation input must be JSON text") from exc + + if isinstance(parsed, dict) and "results" in parsed: + records = _records_from_synthesis_payload(parsed) + if records: + return records + raise ValueError("No successful generated records found in synthesis results") + + if isinstance(parsed, dict) and isinstance(parsed.get("records"), list): + parsed = parsed["records"] + + if isinstance(parsed, dict) and "content" in parsed: + parsed = [parsed] + + if not isinstance(parsed, list): + raise ValueError("evaluation input must be a JSON array, a record object, or synthesis results JSON") + + records: List[Dict[str, Any]] = [] + for idx, item in enumerate(parsed, start=1): + if not isinstance(item, dict): + raise ValueError("Each evaluation record must be a JSON object") + content = item.get("content") + if isinstance(content, dict): + task_type = str(item.get("type") or "QA") + records.append(_make_record(int(item.get("id") or idx), task_type, content)) + continue + if not isinstance(content, str) or not content.strip(): + raise ValueError("Each evaluation record must contain non-empty content") + records.append( + { + "id": int(item.get("id") or idx), + "type": str(item.get("type") or "QA"), + "content": content, + } + ) + + if not records: + raise ValueError("No evaluation records found") + return records + + +class DataQualityEvaluatorService: + def __init__( + self, + evaluator_model_path: Optional[str] = None, + evaluator: Any = None, + ) -> None: + self.evaluator_model_path = ( + evaluator_model_path + or os.environ.get("DATA_QUALITY_EVALUATOR_MODEL_PATH") + or os.environ.get("DATA_EVALUATOR_MODEL_PATH") + or DEFAULT_EVALUATOR_MODEL_PATH + ) + self.evaluator_backend = ( + os.environ.get("DATA_QUALITY_EVALUATOR_BACKEND") + or os.environ.get("DATA_EVALUATOR_BACKEND") + or "vllm" + ).strip().lower() + requested_run_mode = os.environ.get("DATA_QUALITY_EVALUATOR_RUN_MODE", "inprocess").lower() + force_subprocess = os.environ.get("DATA_QUALITY_EVALUATOR_FORCE_SUBPROCESS", "").lower() == "true" + self.run_mode = "subprocess" if requested_run_mode == "subprocess" and force_subprocess else "inprocess" + self.evaluator = evaluator + self._evaluator_error: Optional[str] = None + self._model_lock = threading.RLock() + self._model_executor = ThreadPoolExecutor(max_workers=1, thread_name_prefix="data-quality-evaluator-model") + + def _run_on_model_thread(self, func: Any, *args: Any, **kwargs: Any) -> Any: + return self._model_executor.submit(func, *args, **kwargs).result() + + def _run_exclusive_request(self, func: Any, *args: Any, **kwargs: Any) -> Any: + with SERVICE_REQUEST_LOCK: + return func(*args, **kwargs) + + def _ensure_evaluator_initialized(self, backend: Optional[str] = None) -> None: + requested_backend = (backend or self.evaluator_backend or "vllm").strip().lower() + current_backend = getattr(self.evaluator, "backend", None) + if self.evaluator is not None and current_backend in (None, requested_backend): + self._evaluator_error = None + return + try: + self.evaluator = self._run_on_model_thread( + MedicalDataEvaluator, + self.evaluator_model_path, + backend=requested_backend, + ) + self._evaluator_error = None + except Exception as exc: + self._evaluator_error = str(exc) + raise + + def warmup(self) -> Dict[str, Any]: + if self.run_mode == "subprocess": + return self.health() + try: + self._ensure_evaluator_initialized(self.evaluator_backend) + except Exception: + pass + return self.health() + + def health(self) -> Dict[str, Any]: + return { + "service": "data_quality_evaluator", + "ready": True if self.run_mode == "subprocess" else self.evaluator is not None, + "evaluator_model_path": self.evaluator_model_path, + "evaluator_backend": self.evaluator_backend, + "error": None if self.run_mode == "subprocess" else self._evaluator_error, + } + + def evaluate_text( + self, + file_name: str, + text: str, + target_dimensions: Optional[Iterable[str]] = None, + include_summary: bool = True, + model_path: Optional[str] = None, + backend: Optional[str] = None, + ) -> Dict[str, Any]: + requested_backend = (backend or self.evaluator_backend or "vllm").strip().lower() + evaluator_worker = _is_truthy_env("DATA_QUALITY_EVALUATOR_ISOLATED_WORKER") + if self.run_mode == "subprocess" or (requested_backend == "vllm" and not evaluator_worker): + return self._run_exclusive_request( + self._evaluate_via_subprocess, + file_name=file_name, + text=text, + target_dimensions=target_dimensions, + include_summary=include_summary, + model_path=model_path, + backend=requested_backend, + ) + + return self._evaluate_text_inprocess( + file_name=file_name, + text=text, + target_dimensions=target_dimensions, + include_summary=include_summary, + model_path=model_path, + backend=requested_backend, + ) + + def _evaluate_text_inprocess( + self, + file_name: str, + text: str, + target_dimensions: Optional[Iterable[str]] = None, + include_summary: bool = True, + model_path: Optional[str] = None, + backend: Optional[str] = None, + ) -> Dict[str, Any]: + requested_backend = (backend or self.evaluator_backend or "vllm").strip().lower() + if model_path and model_path != self.evaluator_model_path: + self.evaluator_model_path = model_path + self.evaluator = None + try: + self._ensure_evaluator_initialized(requested_backend) + except Exception as exc: + raise RuntimeError(str(exc)) from exc + if self.evaluator is None: + raise RuntimeError(self._evaluator_error or "Evaluator is not ready") + + records = _parse_evaluation_input(text) + dimensions = _normalize_dimensions(target_dimensions) + with self._model_lock: + evaluation_results = self._run_on_model_thread( + self.evaluator.evaluate, + records, + target_dimensions=dimensions, + ) + + response: Dict[str, Any] = { + "source_file": file_name, + "record_count": len(records), + "dimensions": dimensions, + "results": evaluation_results, + "runtime": ( + self.evaluator.runtime_metadata() + if hasattr(self.evaluator, "runtime_metadata") + else { + "evaluator_backend": getattr(self.evaluator, "backend", "unknown"), + "evaluator_model_path": self.evaluator_model_path, + "vllm_enabled": getattr(self.evaluator, "backend", None) == "vllm", + } + ), + "status": "success", + } + if include_summary: + response["summary"] = self._build_evaluation_summary(records, evaluation_results, dimensions) + return response + + def _evaluate_via_subprocess( + self, + file_name: str, + text: str, + target_dimensions: Optional[Iterable[str]], + include_summary: bool, + model_path: Optional[str], + backend: Optional[str] = None, + ) -> Dict[str, Any]: + normalized_dimensions = _normalize_dimensions(target_dimensions) + worker_payload = { + "file_name": file_name, + "text": text, + "target_dimensions": normalized_dimensions, + "include_summary": include_summary, + "model_path": model_path or self.evaluator_model_path, + "evaluator_backend": backend or self.evaluator_backend or "vllm", + } + worker_code = """ +import json +import os +import sys +payload = json.loads(sys.stdin.read()) +os.environ["DATA_QUALITY_EVALUATOR_MODEL_PATH"] = payload.get("model_path") or "" +os.environ["DATA_QUALITY_EVALUATOR_BACKEND"] = payload.get("evaluator_backend") or "vllm" +os.environ["DATA_QUALITY_EVALUATOR_ISOLATED_WORKER"] = "true" +from data_quality_evaluator_service.core import DataQualityEvaluatorService +service = DataQualityEvaluatorService(evaluator_model_path=payload.get("model_path")) +result = service._evaluate_text_inprocess( + file_name=payload["file_name"], + text=payload["text"], + target_dimensions=payload["target_dimensions"], + include_summary=payload["include_summary"], + model_path=payload.get("model_path"), + backend=payload.get("evaluator_backend"), +) +print("__DATA_QUALITY_EVALUATOR_RESULT__" + json.dumps(result, ensure_ascii=False)) +""" + env = os.environ.copy() + env["DATA_QUALITY_EVALUATOR_RUN_MODE"] = "inprocess" + env["DATA_QUALITY_EVALUATOR_ISOLATED_WORKER"] = "true" + completed = subprocess.run( + [sys.executable, "-c", worker_code], + input=json.dumps(worker_payload, ensure_ascii=False), + text=True, + capture_output=True, + env=env, + cwd=PROJECT_ROOT, + check=False, + ) + if completed.returncode != 0: + error_text = (completed.stderr or completed.stdout or "subprocess failed").strip() + raise RuntimeError(error_text) + return _parse_worker_stdout(completed.stdout) + + def _build_evaluation_summary( + self, + records: List[Dict[str, Any]], + evaluation_results: List[Dict[str, Any]], + dimensions: List[str], + ) -> Dict[str, Any]: + per_dimension: Dict[str, Dict[str, Any]] = {} + for dim in dimensions: + scores = [] + for item in evaluation_results: + score = item.get("scores", {}).get(dim, {}).get("score", -1) + if isinstance(score, int) and score >= 0: + scores.append(score) + pass_count = sum(1 for score in scores if score == 1) + total = len(scores) + pass_rate = (pass_count / total * 100.0) if total else 0.0 + per_dimension[dim] = { + "pass_count": pass_count, + "total": total, + "pass_rate_pct": pass_rate, + } + + task_type_counts: Dict[str, int] = {} + for record in records: + task_type = str(record.get("type") or "QA") + task_type_counts[task_type] = task_type_counts.get(task_type, 0) + 1 + + return { + "record_count": len(records), + "task_type_counts": task_type_counts, + "dimensions": per_dimension, + } diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/requirements.txt b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/requirements.txt new file mode 100644 index 00000000..2c203cfb --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/requirements.txt @@ -0,0 +1,25 @@ +# Independent service production dependencies verified in the 910b +# data-quality-evaluator-service container +# (quay.io/ascend/vllm-ascend:v0.13.0, Python 3.11.14). +# Do not put these heavy model dependencies into operator_src/requirements.txt. +fastapi==0.123.10 +uvicorn==0.40.0 +pydantic==2.12.5 +Jinja2==3.1.6 +requests==2.32.5 +vllm==0.13.0+empty +vllm-ascend==0.13.0 +torch==2.8.0+cpu +torch-npu==2.8.0.post2 +transformers==4.57.6 +tokenizers==0.22.2 +sentencepiece==0.2.1 +einops==0.8.2 +numpy==1.26.4 +safetensors==0.7.0 +typing_extensions==4.15.0 +modelscope==1.34.0 +pandas==3.0.0 + +# Ascend runtime note: vLLM/NPU mode also requires the host Ascend driver, +# CANN runtime, device mounts, and sourced Ascend environment variables. diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/tests/test_app.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/tests/test_app.py similarity index 50% rename from runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/tests/test_app.py rename to runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/tests/test_app.py index d4935cb8..1907e73b 100644 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/tests/test_app.py +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/tests/test_app.py @@ -10,21 +10,19 @@ if PROJECT_ROOT not in sys.path: sys.path.insert(0, PROJECT_ROOT) -from data_synthesis_service.app import create_app +from data_quality_evaluator_service.app import create_app class _FakeService: + def __init__(self): + self.warmup_calls = 0 + def health(self): - return {"ready": True, "model_path": "/models/demo", "service": "data_synthesis"} + return {"ready": True, "service": "data_quality_evaluator"} - def synthesize_text(self, file_name, text, task_types=None, include_metrics=True): - return { - "source_file": file_name, - "task_types": task_types or ["QA", "CoT", "Preference"], - "results": {"QA": [], "CoT": [], "Preference": []}, - "metrics": {} if include_metrics else None, - "status": "success", - } + def warmup(self): + self.warmup_calls += 1 + return self.health() def evaluate_text( self, @@ -42,46 +40,25 @@ def evaluate_text( "results": [{"id": 1, "scores": {"准确性": {"score": 1, "reason": "ok"}}}], "summary": {"record_count": 1} if include_summary else None, "model_path": model_path, + "backend": backend, "status": "success", } -class AppTests(unittest.TestCase): - def test_health_endpoint(self): - client = TestClient(create_app(service=_FakeService())) - response = client.post("/health", json={}) - self.assertEqual(response.status_code, 200) - self.assertTrue(response.json()["ready"]) +class DataQualityEvaluatorAppTests(unittest.TestCase): + def test_app_warmup_runs_on_startup(self): + fake_service = _FakeService() + with TestClient(create_app(service=fake_service)): + pass + self.assertEqual(fake_service.warmup_calls, 1) - def test_health_endpoint_supports_get(self): + def test_health_endpoint(self): client = TestClient(create_app(service=_FakeService())) response = client.get("/health") self.assertEqual(response.status_code, 200) - self.assertTrue(response.json()["ready"]) - - def test_synthesize_endpoint(self): - client = TestClient(create_app(service=_FakeService())) - response = client.post( - "/synthesize-file", - json={"file_name": "demo.txt", "text": "abc"}, - ) - self.assertEqual(response.status_code, 200) - payload = response.json() - self.assertEqual(payload["source_file"], "demo.txt") - self.assertEqual(payload["status"], "success") + self.assertEqual(response.json()["service"], "data_quality_evaluator") def test_evaluate_endpoint(self): - client = TestClient(create_app(service=_FakeService())) - response = client.post( - "/evaluate-file", - json={"file_name": "demo.json", "text": '{"content":"{}"}'}, - ) - self.assertEqual(response.status_code, 200) - payload = response.json() - self.assertEqual(payload["source_file"], "demo.json") - self.assertEqual(payload["status"], "success") - - def test_evaluate_endpoint_accepts_dedicated_model_path(self): client = TestClient(create_app(service=_FakeService())) response = client.post( "/evaluate-file", @@ -89,8 +66,14 @@ def test_evaluate_endpoint_accepts_dedicated_model_path(self): "file_name": "demo.json", "text": '{"content":"{}"}', "model_path": "/model/Qwen/Qwen2.5-7B-Instruct", + "backend": "vllm", }, ) self.assertEqual(response.status_code, 200) payload = response.json() + self.assertEqual(payload["source_file"], "demo.json") self.assertEqual(payload["model_path"], "/model/Qwen/Qwen2.5-7B-Instruct") + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/tests/test_core.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/tests/test_core.py new file mode 100644 index 00000000..2f74049f --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_quality_evaluator_service/tests/test_core.py @@ -0,0 +1,73 @@ +import json +import os +import sys +import unittest +from subprocess import CompletedProcess +from unittest.mock import patch + + +CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) +PROJECT_ROOT = os.path.dirname(os.path.dirname(CURRENT_DIR)) +if PROJECT_ROOT not in sys.path: + sys.path.insert(0, PROJECT_ROOT) + +from data_quality_evaluator_service.core import DataQualityEvaluatorService + + +class _FakeEvaluator: + backend = "vllm" + + def evaluate(self, data_list, target_dimensions=None): + dimensions = list(target_dimensions or ["准确性"]) + return [ + { + "id": 1, + "scores": {dimension: {"score": 1, "reason": "ok"} for dimension in dimensions}, + } + ] + + def runtime_metadata(self): + return { + "evaluator_backend": self.backend, + "evaluator_model_path": "/model/Qwen/Qwen2.5-7B-Instruct", + "vllm_enabled": True, + "visible_npus": "6", + } + + +class DataQualityEvaluatorCoreTests(unittest.TestCase): + @patch("data_quality_evaluator_service.core.subprocess.run") + def test_vllm_evaluation_routes_to_isolated_worker(self, run_mock): + run_mock.return_value = CompletedProcess( + args=["python"], + returncode=0, + stdout='__DATA_QUALITY_EVALUATOR_RESULT__{"status":"success","runtime":{"evaluator_backend":"vllm","vllm_enabled":true}}', + stderr="", + ) + service = DataQualityEvaluatorService() + + result = service.evaluate_text( + "records.json", + json.dumps([{"id": 1, "type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}]), + ) + + run_mock.assert_called_once() + self.assertEqual(result["runtime"]["evaluator_backend"], "vllm") + self.assertTrue(result["runtime"]["vllm_enabled"]) + + def test_rule_backend_can_evaluate_inprocess(self): + service = DataQualityEvaluatorService(evaluator=_FakeEvaluator()) + + result = service.evaluate_text( + "records.json", + json.dumps([{"id": 1, "type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}]), + backend="rule", + ) + + self.assertEqual(result["status"], "success") + self.assertEqual(result["record_count"], 1) + self.assertIn("准确性", result["summary"]["dimensions"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/data_synthesizer.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/data_synthesizer.py deleted file mode 100644 index a01cfdea..00000000 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/data_synthesizer.py +++ /dev/null @@ -1,1337 +0,0 @@ -import json -import re -import random -from pathlib import Path -from typing import List, Dict, Any, Optional - -try: - from vllm import LLM, SamplingParams - from vllm.sampling_params import StructuredOutputsParams -except Exception: # pragma: no cover - 仅用于无 vllm 的测试环境 - LLM = None - StructuredOutputsParams = None - - class SamplingParams: # type: ignore - def __init__(self, **kwargs): - self.kwargs = kwargs - for key, value in kwargs.items(): - setattr(self, key, value) - -try: - from jinja2 import Template -except Exception: # pragma: no cover - 仅用于无 jinja2 的测试环境 - class Template: # type: ignore - def __init__(self, text: str): - self.text = text - - def render(self, **kwargs): - rendered = self.text - for k, v in kwargs.items(): - rendered = rendered.replace("{{ " + k + " }}", str(v)) - return rendered - -class MedicalDataSynthesizer: - def __init__(self, model_path: Optional[str], llm_instance: Any = None): - """ - :param model_path: 模型路径。若传入 llm_instance,可为 None。 - :param llm_instance: 可注入的 LLM 对象(便于单元测试)。 - """ - if llm_instance is not None: - self.llm = llm_instance - else: - if not model_path: - raise ValueError("model_path 不能为空(未注入 llm_instance 时)") - if LLM is None: - raise ImportError("未安装 vllm,无法初始化模型。请先安装 vllm-ascend / vllm。") - self.llm = LLM( - model=model_path, - trust_remote_code=True, - tensor_parallel_size=1, - gpu_memory_utilization=0.85, - max_model_len=8192, - dtype="float16" - ) - self._qa_native_chat_template = self._load_native_chat_template(model_path) - self._qa_uses_native_template = self._qa_native_chat_template is not None - self._init_templates() - self.required_fields = { - "QA": ["question", "answer"], - "CoT": ["question", "rationale", "final_answer"], - "Preference": ["question", "chosen", "rejected", "preference_reason"] - } - self.length_limits = { - "QA": {"question": 220, "answer": 160}, - "CoT": {"question": 220, "rationale": 2000, "final_answer": 220}, - "Preference": {"question": 220, "chosen": 180, "rejected": 180, "preference_reason": 220}, - } - self.meta_phrases = [ - "嗯,用户", "用户让我", "首先,我需要", "只输出 json", "json格式", - "思考过程", "推理过程", "", "<|im_start|>", "<|im_end|>", - ] - self.weak_preference_reasons = { - "chosen 提供了更多可用信息。", - "chosen 更好。", - "chosen 更准确。", - } - - def _load_native_chat_template(self, model_path: Optional[str]) -> Optional[str]: - if not model_path: - return None - - config_path = Path(model_path) / "tokenizer_config.json" - if not config_path.exists(): - return None - - try: - tokenizer_config = json.loads(config_path.read_text(encoding="utf-8")) - except Exception: - return None - - chat_template = tokenizer_config.get("chat_template") - return chat_template if isinstance(chat_template, str) and chat_template.strip() else None - - def _render_native_chat_template(self, messages: List[Dict[str, str]], enable_thinking: bool) -> str: - if not self._qa_native_chat_template: - raise ValueError("native chat template unavailable") - - parts: List[str] = [] - if messages and messages[0].get("role") == "system": - parts.append("<|im_start|>system\n" + messages[0].get("content", "") + "<|im_end|>\n") - remaining = messages[1:] - else: - remaining = messages - - for message in remaining: - role = message.get("role", "") - content = message.get("content", "") - parts.append(f"<|im_start|>{role}\n{content}<|im_end|>\n") - - parts.append("<|im_start|>assistant\n") - if not enable_thinking: - parts.append("\n\n\n\n") - return "".join(parts) - - def _init_templates(self): - # QA 模板:保持原样,它是好的 - self.qa_template = Template("""<|im_start|>system -你是一个专业的医学专家。请基于【医疗文本】生成一个JSON格式的问答对。 -你必须只输出 JSON,不要输出额外解释,不要输出 或推理过程。 -输出要求(必须严格遵守): -1) 仅输出一个 JSON 对象,且字段仅有 question 与 answer; -2) 不得输出任何元话术(如“首先/用户/根据以上”)与思考内容; -3) answer 简明,控制在80字以内。 -<|im_end|> -<|im_start|>user -【医疗文本】:患者男,30岁,主诉牙痛3天。查体见右下阻生智齿。 -<|im_end|> -<|im_start|>assistant -{ - "question": "患者的主诉和查体结果提示什么问题?", - "answer": "患者主诉牙痛3天,查体发现右下阻生智齿,提示可能存在智齿冠周炎或牙髓炎。" -} -<|im_end|> -<|im_start|>user -【医疗文本】:女性,65岁。主诉:胸闷气短反复发作1年。查体及辅助检查:心电图ST段抬高。 -<|im_end|> -<|im_start|>assistant -{ - "question": "患者的主诉和查体结果提示什么问题?", - "answer": "胸闷气短伴ST段抬高,提示急性冠脉综合征风险,建议尽快心内科评估。" -} -<|im_end|> -<|im_start|>user -【医疗文本】:{{ context }} -<|im_end|> -<|im_start|>assistant -""") - - # 🟢 修正 CoT 模板:去除换行符,将示例写成紧凑的单行,避免 Python 字符串转义灾难 - self.cot_template = Template("""<|im_start|>system -你是一个资深的临床医生。请针对【医疗问题】生成JSON格式的思维链推理。 -逻辑路径:症状 -> 检查 -> 诊断 -> 治疗。 -你必须只输出 JSON,不要输出额外解释,不要输出 标签。 - 输出要求(必须严格遵守): - 1) 仅输出一个 JSON 对象,字段仅有 question/rationale/final_answer; - 2) rationale 使用条目化步骤表达(建议不少于6步); - 3) 禁止元话术与角色说明。 -<|im_end|> -<|im_start|>user -【医疗问题】:感冒引起的发热应该如何处理? -<|im_end|> -<|im_start|>assistant -{ - "question": "感冒引起的发热应该如何处理?", - "rationale": "1.症状分析:患者因感冒出现发热。2.辅助检查:必要时查血常规。3.初步判断:以上呼吸道感染为主。4.风险评估:关注高热与脱水。5.治疗策略:物理降温为主。6.用药原则:高热可口服解热镇痛药。", - "final_answer": "建议多休息、多饮水。若体温超过38.5℃,可服用退热药;否则采用物理降温。" -} -<|im_end|> -<|im_start|>user -【医疗问题】:男性,45岁。主诉:持续性干咳3天。查体及辅助检查:CT示斑片影。 -<|im_end|> -<|im_start|>assistant -{ - "question": "男性,45岁。主诉:持续性干咳3天。查体及辅助检查:CT示斑片影。", - "rationale": "1.症状提取:持续性干咳3天。2.关键检查:CT示斑片影。3.病因推断:以感染性肺部病变优先。4.鉴别方向:需与非感染性间质病变区分。5.进一步检查:血常规与炎症指标。6.处置建议:呼吸专科评估并随访影像。", - "final_answer": "当前首先考虑肺部炎症性病变,建议完善感染评估并尽快呼吸专科复诊。" -} -<|im_end|> -<|im_start|>user -【医疗问题】:{{ question }} -<|im_end|> -<|im_start|>assistant -""") - - # 偏好数据模板:生成 chosen/rejected 供偏好学习(含示例,减少叙述体输出) - self.preference_template = Template("""<|im_start|>system -你是医疗数据工程师。请基于【医疗问题】输出偏好学习样本(JSON)。 -要求: -1) chosen:高质量、准确且安全; -2) rejected:包含明显缺陷(如不完整、轻微逻辑问题或不够相关); -3) 输出字段必须为:question/chosen/rejected/preference_reason。 -你必须只输出 JSON,不要输出额外解释,不要输出 标签。 -chosen 与 rejected 均尽量简洁(建议各不超过80字)。 -preference_reason 必须具体说明“为什么 chosen 更好”,不得写空泛套话。 -<|im_end|> -<|im_start|>user -【医疗问题】:女性,65岁。主诉:胸闷气短反复发作1年。查体及辅助检查:心电图ST段抬高。 -<|im_end|> -<|im_start|>assistant -{ - "question": "女性,65岁。主诉:胸闷气短反复发作1年。查体及辅助检查:心电图ST段抬高。", - "chosen": "胸闷气短伴ST段抬高,优先考虑急性冠脉综合征,建议立即心电监护与心肌标志物复查。", - "rejected": "可能只是普通疲劳,先回家休息观察即可。", - "preference_reason": "chosen 结合了关键检查异常并给出及时处置;rejected 忽略高危心电图信号,存在安全风险。" -} -<|im_end|> -<|im_start|>user -【医疗问题】:{{ question }} -<|im_end|> -<|im_start|>assistant -""") - - self.task_templates = { - "QA": self.qa_template, - "CoT": self.cot_template, - "Preference": self.preference_template - } - - self.repair_templates = { - "QA": Template("""<|im_start|>system -你是JSON修复器。请把给定文本修复为合法JSON对象,且仅包含字段 question/answer。 -要求: -1) 只输出一个 JSON 对象; -2) 不要输出 、解释、markdown; -3) answer 控制在80字内。 -<|im_end|> -<|im_start|>user -【原始输入】:{{ source_text }} -【候选输出】:{{ raw_output }} -请修复为目标JSON。 -<|im_end|> -<|im_start|>assistant -"""), - "CoT": Template("""<|im_start|>system -你是JSON修复器。请把给定文本修复为合法JSON对象,且仅包含字段 question/rationale/final_answer。 -要求: -1) 只输出一个 JSON 对象; -2) rationale 使用步骤化表达(建议6步); -3) 不要输出 、解释、markdown。 -<|im_end|> -<|im_start|>user -【原始输入】:{{ source_text }} -【候选输出】:{{ raw_output }} -请修复为目标JSON。 -<|im_end|> -<|im_start|>assistant -"""), - "Preference": Template("""<|im_start|>system -你是JSON修复器。请把给定文本修复为合法JSON对象,且仅包含字段 question/chosen/rejected/preference_reason。 -要求: -1) 只输出一个 JSON 对象; -2) chosen 为更优回答,rejected 为较差回答,preference_reason 必须具体; -3) 不要输出 、解释、markdown。 -<|im_end|> -<|im_start|>user -【原始输入】:{{ source_text }} -【候选输出】:{{ raw_output }} -请修复为目标JSON。 -<|im_end|> -<|im_start|>assistant -"""), - } - - def _distill_text(self, text: str) -> str: - """轻量数据蒸馏:保留核心症状/检查信息,删除冗余语气词。""" - distilled = re.sub(r"(请问|可能|大概|有点|非常|真的)", "", text) - distilled = re.sub(r"\s+", "", distilled) - return f"[蒸馏]{distilled}" - - def _augment_text(self, text: str) -> List[str]: - """轻量数据增强:结构改写 + 关键信息重排。""" - variants = [ - f"患者信息:{text}", - f"病例摘要:{text}", - f"请根据以下临床片段生成训练数据:{text}", - f"【主诉与检查】{text}", - f"医学文本(需结构化):{text}" - ] - - # 若文本包含句号,尝试做结构重排增强 - parts = [p for p in re.split(r"[。;;]", text) if p.strip()] - if len(parts) >= 2: - reordered = ";".join(parts[1:] + parts[:1]) + "。" - variants.append(f"重排病历:{reordered}") - return variants - - def build_training_corpus( - self, - raw_inputs: List[str], - target_size: int, - source_ratio: Optional[Dict[str, float]] = None, - seed: int = 42 - ) -> List[Dict[str, str]]: - """ - 构建训练语料池,支持原始/增强/蒸馏数据配比。 - 返回格式: [{"source": "original|augmented|distilled", "text": "..."}, ...] - """ - if not raw_inputs: - return [] - - if source_ratio is None: - source_ratio = {"original": 0.4, "augmented": 0.4, "distilled": 0.2} - - ratio_sum = sum(source_ratio.values()) - if ratio_sum <= 0: - raise ValueError("source_ratio 总和必须 > 0") - - normalized_ratio = {k: v / ratio_sum for k, v in source_ratio.items()} - - random.seed(seed) - original_pool = list(raw_inputs) - augmented_pool = [aug for text in raw_inputs for aug in self._augment_text(text)] - distilled_pool = [self._distill_text(text) for text in raw_inputs] - - source_pools = { - "original": original_pool, - "augmented": augmented_pool, - "distilled": distilled_pool - } - - allocated = { - k: int(target_size * normalized_ratio.get(k, 0.0)) - for k in ["original", "augmented", "distilled"] - } - - remain = target_size - sum(allocated.values()) - for key in ["original", "augmented", "distilled"]: - if remain <= 0: - break - allocated[key] += 1 - remain -= 1 - - mixed = [] - for source_name, cnt in allocated.items(): - pool = source_pools[source_name] - if not pool: - continue - for i in range(cnt): - mixed.append({"source": source_name, "text": pool[i % len(pool)]}) - - random.shuffle(mixed) - return mixed - - def _clean_json_string(self, text: str) -> str: - text = text.strip() - - # 移除 Qwen 系列常见的思考段,避免污染 JSON - text = re.sub(r"[\s\S]*?", "", text, flags=re.IGNORECASE) - # 兼容未闭合 think 标签 - text = re.sub(r"[\s\S]*$", "", text, flags=re.IGNORECASE) - text = re.sub(r"<\|im_start\|>think[\s\S]*?<\|im_end\|>", "", text, flags=re.IGNORECASE) - - # 移除 Markdown 标记 - text = re.sub(r"^```json", "", text, flags=re.MULTILINE) - text = re.sub(r"^```", "", text, flags=re.MULTILINE) - text = text.strip() - - # 🟢 增强:处理模型输出真实换行符的情况 - # 将 JSON 值里的真实换行符替换为空格,防止 json.loads 失败 - # (这是一个简单的 trick,防止 "rationale": "第一行\n第二行" 报错) - # text = text.replace('\n', ' ') - # 上面这行太暴力,可能会破坏 JSON 结构,改用 strict=False 并在失败时尝试修复 - - extracted = self._extract_first_json_object(text) - return extracted if extracted else text - - def _repair_json_syntax_only(self, text: str) -> str: - """Only fix common JSON syntax issues; never invent missing content.""" - repaired = text.strip() - repaired = re.sub(r",(\s*[}\]])", r"\1", repaired) - repaired = repaired.replace(",}", "}").replace(",]", "]") - repaired = repaired.replace("“", '"').replace("”", '"') - return repaired - - def _extract_first_json_object(self, text: str) -> Optional[str]: - start = text.find("{") - if start == -1: - return None - - in_str = False - escaped = False - depth = 0 - for i in range(start, len(text)): - ch = text[i] - if in_str: - if escaped: - escaped = False - elif ch == "\\": - escaped = True - elif ch == '"': - in_str = False - continue - - if ch == '"': - in_str = True - elif ch == "{": - depth += 1 - elif ch == "}": - depth -= 1 - if depth == 0: - return text[start:i + 1] - - # 兜底:首个 { 到最后一个 } - last = text.rfind("}") - if last > start: - return text[start:last + 1] - return None - - def _strip_reasoning_text(self, text: str) -> str: - t = text.strip() - t = re.sub(r"[\s\S]*?", "", t, flags=re.IGNORECASE) - t = re.sub(r"[\s\S]*$", "", t, flags=re.IGNORECASE) - t = re.sub(r"<\|im_start\|>think[\s\S]*?<\|im_end\|>", "", t, flags=re.IGNORECASE) - t = re.sub(r"^```json", "", t, flags=re.MULTILINE) - t = re.sub(r"^```", "", t, flags=re.MULTILINE) - t = re.sub(r"\s+", " ", t).strip() - return t - - def _looks_like_meta_or_thought(self, text: str) -> bool: - if not text: - return True - lower = text.lower().strip() - for p in self.meta_phrases: - if p.lower() in lower: - return True - if lower.startswith("嗯") or lower.startswith("好的") or lower.startswith("首先"): - return True - return False - - def _check_length_limit(self, task_type: str, data: Dict[str, Any]) -> bool: - limits = self.length_limits.get(task_type, {}) - for k, max_len in limits.items(): - v = data.get(k) - if isinstance(v, str) and len(v.strip()) > max_len: - return False - return True - - def _passes_task_quality( - self, - task_type: str, - data: Dict[str, Any], - source_text: Optional[str] = None, - ) -> bool: - if not self._check_length_limit(task_type, data): - return False - - if source_text and self._has_obvious_source_contradiction(source_text, data): - return False - - if task_type == "QA": - q = str(data.get("question", "")).strip() - a = str(data.get("answer", "")).strip() - if self._looks_like_meta_or_thought(q) or self._looks_like_meta_or_thought(a): - return False - if len(a) < 8: - return False - return True - - if task_type == "CoT": - q = str(data.get("question", "")).strip() - r = str(data.get("rationale", "")).strip() - f = str(data.get("final_answer", "")).strip() - if ( - self._looks_like_meta_or_thought(q) - or self._looks_like_model_monologue(q) - or self._looks_like_meta_or_thought(r) - or self._looks_like_meta_or_thought(f) - ): - return False - # 简单步骤判定,避免输出成口语段落 - step_hits = len(re.findall(r"(\d+[\.、]|步骤\d+|->)", r)) - if step_hits < 3: - return False - return True - - if task_type == "Preference": - c = str(data.get("chosen", "")).strip() - rj = str(data.get("rejected", "")).strip() - pr = str(data.get("preference_reason", "")).strip() - if any(self._looks_like_meta_or_thought(x) or self._looks_like_model_monologue(x) for x in [c, rj, pr]): - return False - if c == rj: - return False - if pr in self.weak_preference_reasons: - return False - return True - - return True - - def _looks_like_model_monologue(self, text: str) -> bool: - value = (text or "").strip() - if not value: - return False - monologue_patterns = [ - r"我需要", - r"我会", - r"我首先", - r"让我", - r"这让我", - r"我认为", - r"我推测", - r"需要综合这些信息", - ] - return any(re.search(pattern, value) for pattern in monologue_patterns) - - def _contains_positive_recommendation(self, text: str, terms: List[str]) -> bool: - value = text or "" - for term in terms: - for match in re.finditer(re.escape(term), value): - prefix = value[max(0, match.start() - 12):match.start()] - if any(marker in prefix for marker in ["不", "无", "无需", "不需", "忽视", "拒绝", "暂不", "不能", "避免", "慎用", "除非", "仅在"]): - continue - return True - return False - - def _is_dka_source(self, source: str) -> bool: - return ( - ("血糖" in source) - and ("尿酮" in source or "酮体" in source) - and ("pH" in source or "HCO3" in source or "酸中毒" in source) - ) - - def _is_acute_stroke_source(self, source: str) -> bool: - return ( - ("突发" in source) - and ("肢体无力" in source or "言语不清" in source or "NIHSS" in source) - and ("CT未见出血" in source or ("CT" in source and "未见出血" in source)) - ) - - def _is_bacterial_pneumonia_source(self, source: str) -> bool: - return ( - ("发热" in source and ("咳嗽" in source or "气促" in source)) - and ("白细胞" in source or "中性粒细胞" in source or "CRP" in source) - and ("片状浸润" in source or "湿啰音" in source or "肺炎" in source) - ) - - def _has_unapproved_english_tokens(self, source_text: str, generated: str) -> bool: - if not generated: - return False - - if not re.search(r"[\u4e00-\u9fff]", source_text or ""): - return False - - forbidden = { - "insulin", "volume", - } - for token in re.findall(r"[A-Za-z][A-Za-z0-9+\-]*", generated): - normalized = token.lower().strip("+-") - if normalized in forbidden: - return True - return False - - def _has_obvious_source_contradiction(self, source_text: str, data: Dict[str, Any]) -> bool: - source = source_text or "" - generated = " ".join( - str(v) - for v in data.values() - if isinstance(v, (str, int, float)) - ) - if self._has_unapproved_english_tokens(source, generated): - return True - - def has_forbidden_without_negation(term: str) -> bool: - for m in re.finditer(re.escape(term), generated): - window = generated[max(0, m.start() - 48): m.end() + 40] - if any(marker in window for marker in ["排除", "不考虑", "不符合", "不适当", "不恰当", "无关", "否定", "不是", "不应", "不得", "禁止", "无需", "不需", "不常规", "非首选", "不作为", "避免", "慎用", "除非", "仅在", "不推荐"]): - continue - return True - return False - - if any(term in generated for term in ["preference 中", "Preference 中", "chosen 应", "rejected 应", "作为 chosen", "字段固定为", "既往规则", "根据规则", "prompt", "原始的诊断建议"]): - return True - if any(term in generated for term in ["曓", "�"]): - return True - if re.search(r"依据\d{2,}", generated): - return True - if re.search(r"\binsulin\b", generated, flags=re.IGNORECASE): - return True - - contradiction_pairs = [ - ("男", ["女性", "妇科", "卵巢", "黄体破裂", "子宫", "妊娠"]), - ("女", ["男性", "睾丸", "前列腺"]), - ] - for source_marker, forbidden_terms in contradiction_pairs: - if source_marker in source and any(has_forbidden_without_negation(term) for term in forbidden_terms): - return True - - if "腹股沟" in source and "阶梯状液气平" in source: - unrelated = ["睾丸扭转", "黄体破裂", "卵巢囊肿", "盆腔炎"] - final_answer = str(data.get("final_answer", "")) - chosen = str(data.get("chosen", "")) - if data.keys() >= {"chosen", "rejected", "preference_reason"}: - rejected = str(data.get("rejected", "")) - if any(term in rejected for term in unrelated): - return True - if any(term in chosen for term in unrelated): - return True - if not ("腹股沟疝" in chosen and "肠梗阻" in chosen): - return True - if any(has_forbidden_without_negation(term) for term in unrelated): - return True - if any(term in generated for term in ["穿孔", "引流", "推挤", "减压"]): - return True - if final_answer: - unsafe_delay = r"(延迟|延误|推迟|暂缓|暂不|不急).{0,12}(外科|手术|评估|处理)|观察并.{0,8}(延迟|延误|推迟|暂缓)" - for match in re.finditer(unsafe_delay, final_answer): - prefix = final_answer[max(0, match.start() - 6):match.start()] - if any(marker in prefix for marker in ["避免", "防止", "以免", "减少"]): - continue - return True - if "观察" in final_answer and not any(term in final_answer for term in ["外科评估", "急诊", "手术", "尽快", "及时"]): - return True - - if "食管裂孔疝" in source: - chosen = str(data.get("chosen", "")) - rejected = str(data.get("rejected", "")) - if ( - self._contains_positive_recommendation(rejected, ["手术治疗", "手术评估", "外科评估"]) - and not any(term in chosen for term in ["食管裂孔疝", "裂孔疝", "手术", "外科评估"]) - ): - return True - - if all(term in source for term in ["II", "III", "aVF", "ST段抬高"]): - if any(term in generated for term in ["左心上室", "前壁心肌梗死", "高侧壁心肌梗死", "冠状动脉栓塞", "心尖端", "非心尖"]): - return True - if any(term in generated for term in ["心脏起搏器检查", "心包反射", "心包疾病"]): - return True - if re.search(r"排除.{0,10}心肌梗死|心肌梗死.{0,10}排除", generated): - return True - - if self._is_dka_source(source): - chosen = str(data.get("chosen", "")) - rejected = str(data.get("rejected", "")) - final_answer = str(data.get("final_answer", "")) - if re.search(r"HCO3-?.{0,8}(增高|升高|增加|偏高)", generated, flags=re.IGNORECASE): - return True - if any(term in generated for term in ["抗激素", "神经系统受损原因", "神经系统损伤", "神经系统受损"]): - return True - if "高血压" not in source and any(term in generated for term in ["原发性高血压", "高血压病"]): - return True - if not any(term in generated for term in ["糖尿病酮症酸中毒", "酮症酸中毒", "DKA"]): - return True - if has_forbidden_without_negation("碳酸氢钠") and "pH 6.9" not in source and "pH<6.9" not in source: - return True - if data.keys() >= {"chosen", "rejected", "preference_reason"}: - if not any(term in chosen for term in ["胰岛素", "补液", "液体复苏"]): - return True - if ( - self._contains_positive_recommendation(chosen, ["碳酸氢钠", "抗生素"]) - and self._contains_positive_recommendation(rejected, ["胰岛素", "补液", "液体复苏"]) - ): - return True - if final_answer and not any(term in final_answer for term in ["胰岛素", "补液", "液体复苏"]): - return True - - if self._is_acute_stroke_source(source): - if "缺抗性卒中" in generated: - return True - if any(term in generated for term in ["脑干梗死", "血管痉挛", "阿瑟曼征", "侧枝循环障碍"]): - return True - if has_forbidden_without_negation("SPECT"): - return True - if data.keys() >= {"chosen", "rejected", "preference_reason"}: - rejected = str(data.get("rejected", "")) - if self._contains_positive_recommendation(rejected, ["机械取栓", "取栓", "再灌注"]): - return True - if re.search(r"(先行|优先|先做|先完善).{0,12}(MRI|磁共振).{0,18}(再|后).{0,8}(溶栓|取栓|再灌注)", generated): - return True - if re.search(r"(延后|延迟|暂缓|推迟).{0,10}(溶栓|取栓|再灌注)", generated): - return True - if "CT未见出血" in source and "溶栓" in generated and re.search(r"(不应|不能|无需|不推荐).{0,8}溶栓", generated): - return True - - if self._is_bacterial_pneumonia_source(source): - chosen = str(data.get("chosen", "")) - rejected = str(data.get("rejected", "")) - if any(term in generated for term in ["腹股沟疝", "肠梗阻", "腹股沟包块"]): - return True - if "CRP升高" in source and any(term in generated for term in ["正常CRP", "CRP正常", "CRP不高", "CRP未升高"]): - return True - if any(term in generated for term in ["无呼吸道症状", "无细菌证据", "没有细菌感染证据", "缺乏细菌感染证据"]): - return True - if has_forbidden_without_negation("病毒感染"): - return True - if data.keys() >= {"chosen", "rejected", "preference_reason"}: - chosen_antiviral = self._contains_positive_recommendation(chosen, ["抗病毒"]) - rejected_antibiotic = self._contains_positive_recommendation(rejected, ["抗生素", "抗感染"]) - if chosen_antiviral and rejected_antibiotic: - return True - if not any(term in chosen for term in ["抗生素", "抗感染", "细菌性肺炎"]): - return True - - return False - - def _build_source_guardrail(self, source_text: str, task_type: Optional[str] = None) -> str: - source = source_text or "" - rules: List[str] = [] - if "男" in source: - rules.append("病例为男性。") - if "女" in source: - rules.append("病例为女性。") - if "腹股沟" in source and "包块" in source: - rules.append("腹股沟包块合并阶梯状液气平时,应围绕嵌顿性腹股沟疝合并肠梗阻分析。") - rules.append("所有字段禁止出现穿孔、引流、推挤、减压等原文未给出的并发症或处置。") - rules.append("CoT 任务中,final_answer 必须建议尽快外科或急诊外科评估,不得建议观察、延迟外科评估或延迟手术。") - rules.append("Preference 任务中,chosen 必须字面包含:嵌顿性腹股沟疝合并肠梗阻,并建议尽快外科评估;不得把卵巢囊肿、盆腔炎、睾丸扭转、阑尾肿瘤等作为 chosen。") - rules.append("Preference 任务中,rejected 不得是疾病名,严禁输出卵巢囊肿、盆腔炎、睾丸扭转等其他诊断名称;必须用同一病例的低质量处理建议作为 rejected,例如仅建议观察、延误外科评估、忽视肠梗阻证据或未及时处理嵌顿疝。") - if "食管裂孔疝" in source: - rules.append("食管裂孔疝病例应同时覆盖反流性食管炎、食管裂孔疝和反流相关咳喘。") - rules.append("Preference 任务中,chosen 应是更完整答案;不得把手术治疗、手术评估或外科评估作为 rejected 的优点。") - if all(term in source for term in ["II", "III", "aVF", "ST段抬高"]): - rules.append("II、III、aVF导联ST段抬高合并肌钙蛋白升高时,应明确为急性下壁STEMI或下壁心肌梗死。") - rules.append("处理建议应聚焦急诊心内科评估、抗栓治疗、冠脉造影评估和再灌注策略。") - if self._is_dka_source(source): - rules.append("血糖显著升高、尿酮体阳性、pH/HCO3-提示酸中毒时,应围绕糖尿病酮症酸中毒分析。") - rules.append("处理原则必须包括补液或液体复苏、静脉胰岛素、钾/电解质监测与纠正,并寻找诱因。") - if task_type == "Preference": - rules.append("Preference 的 chosen 必须同时包含诊断和处理:糖尿病酮症酸中毒、补液、静脉胰岛素、电解质监测纠正;rejected 应写同病例低质量处置,例如仅观察或只控制血糖而遗漏补液和电解质管理。") - rules.append("治疗表述只使用中文胰岛素,不使用英文 insulin;不要输出编号残片。") - rules.append("只输出上述诊断依据和处理原则,不扩展原文未提供的其他系统病因或常规外治疗。") - if self._is_acute_stroke_source(source): - rules.append("突发偏瘫/言语不清且头颅CT未见出血时,应按急性缺血性卒中路径分析。") - rules.append("处置应包括卒中中心评估、静脉溶栓时间窗/禁忌评估、必要时机械取栓评估、血压和血糖管理。") - rules.append("不得无依据写脑干梗死、血管痉挛或SPECT;不得要求先做MRI/SPECT而延误溶栓或再灌注评估。") - if task_type == "Preference": - rules.append("Preference 中 chosen 不得写既往规则、根据规则或 prompt 话术;rejected 不得否定机械取栓或再灌注评估,应写同病例低质量回答,例如仅观察、延误溶栓、忽视CT未见出血或忽视时间窗。") - if self._is_bacterial_pneumonia_source(source): - rules.append("儿童发热咳嗽、湿啰音、白细胞/中性粒细胞/CRP升高和片状浸润影时,应优先围绕细菌性肺炎分析。") - if task_type == "Preference": - rules.append("Preference 中 chosen 应支持经验性抗生素或抗感染治疗及支持治疗;不得把抗病毒优先方案作为 chosen。") - rules.append("Preference 中 rejected 必须是同病例低质量回答,例如仅抗病毒、仅观察、延误抗生素或忽视细菌感染证据;不得写不适用、信息不足、妇科疾病或其他无关内容。") - rules.append("Preference 的 rejected 不得写无呼吸道症状,不得写无细菌证据,不得写缺乏细菌感染证据;因为原始病例已经有发热咳嗽、白细胞/CRP升高和片状浸润影。") - if rules: - rules.append("以上规则只用于约束生成,禁止把规则原句、字段名或 prompt 要求写入输出内容。") - return " ".join(rules) - - def _render_prompt(self, task_type: str, text: str) -> str: - if task_type not in self.task_templates: - raise ValueError(f"不支持的 task_type: {task_type}") - - if task_type == "QA": - return self._render_qa_fast_prompt(text) - if task_type == "CoT": - return self._render_cot_native_prompt(text) - if task_type == "Preference": - return self._render_preference_native_prompt(text) - raise ValueError(f"不支持的 task_type: {task_type}") - - def _render_qa_fast_prompt(self, text: str) -> str: - compact = text.strip() - guardrail = self._build_source_guardrail(compact, "QA") - if self._qa_uses_native_template: - messages = [ - { - "role": "system", - "content": ( - "Generate one medical QA JSON object from the source text. " - "Output JSON only. Do not output explanations or . " - "Use exactly two fields: question and answer. " - "Keep answer concise and grounded in the source text. " - f"{guardrail}" - ), - }, - { - "role": "user", - "content": compact, - }, - ] - return self._render_native_chat_template(messages, enable_thinking=False) - - return ( - "<|im_start|>system\n" - "Generate one medical QA JSON object from the source text. " - "Output JSON only. Do not output explanations or . " - "Use exactly two fields: question and answer. " - "Keep answer concise and grounded in the source text. " - f"{guardrail}\n" - "<|im_end|>\n" - "<|im_start|>user\n" - f"{compact}\n" - "<|im_end|>\n" - "<|im_start|>assistant\n" - "\n\n\n\n" - ) - - def _render_cot_native_prompt(self, text: str) -> str: - compact = text.strip() - guardrail = self._build_source_guardrail(compact, "CoT") - if self._qa_uses_native_template: - messages = [ - { - "role": "system", - "content": ( - "你是资深临床医生。请基于用户给出的中文病例生成一个 CoT JSON 对象。" - "只能输出 JSON,不要输出解释或 。" - "字段固定为 question、rationale、final_answer。" - "question 必须是一个简短的临床问题,不得写模型自述、推理过程、'我需要'或'这让我'。" - "rationale 必须是一个中文字符串,不要使用数组;必须包含六个编号:1. 2. 3. 4. 5. 6.。" - "每个编号步骤必须引用输入病例中的症状、检查或处置依据,每步尽量不超过35字。" - "final_answer 必须与病例一致,不得引入输入中不存在的症状或检查。" - f"{guardrail}" - ), - }, - {"role": "user", "content": compact}, - ] - return self._render_native_chat_template(messages, enable_thinking=False) - return self.cot_template.render(question=text) - - def _render_preference_native_prompt(self, text: str) -> str: - compact = text.strip() - guardrail = self._build_source_guardrail(compact, "Preference") - if self._qa_uses_native_template: - messages = [ - { - "role": "system", - "content": ( - "你是医疗数据工程师。请基于用户给出的中文病例生成一个偏好学习 JSON 对象。" - "只能输出 JSON,不要输出解释或 。" - "字段固定为 question、chosen、rejected、preference_reason。" - "chosen 必须是准确、安全、完整的医学回答。" - "rejected 必须是明显较差但与同一病例相关的回答,不得写成无关疾病。" - "rejected 应写成同一病例下的错误处置、遗漏关键证据或不安全建议,不要列举与病例性别/部位冲突的其他疾病。" - "每个字段保持简短,避免长篇背景解释。" - "如果病例为男性,禁止输出妇科疾病;如果病例为女性,禁止输出男性生殖系统疾病。" - f"{guardrail}" - "preference_reason 必须具体比较 chosen 为什么更好。" - ), - }, - {"role": "user", "content": compact}, - ] - return self._render_native_chat_template(messages, enable_thinking=False) - return self.preference_template.render(question=text) - - def _render_repair_prompt( - self, - task_type: str, - source_text: str, - raw_output: str, - repair_note: Optional[str] = None, - ) -> str: - if task_type not in self.repair_templates: - raise ValueError(f"不支持的 task_type: {task_type}") - # 限制候选输出长度,避免修复阶段 prompt 过长 - clipped = (raw_output or "")[:2400] - note = f"\n质量校验失败原因:{repair_note}" if repair_note else "" - if self._qa_uses_native_template: - fields = "/".join(self.required_fields.get(task_type, [])) - guardrail = self._build_source_guardrail(source_text, task_type) - groin_repair_rules = "" - if "腹股沟" in (source_text or "") and "阶梯状液气平" in (source_text or ""): - groin_repair_rules = ( - "腹股沟包块合并阶梯状液气平时,chosen 必须写嵌顿性腹股沟疝合并肠梗阻并建议尽快外科评估。" - "腹股沟包块合并阶梯状液气平的 Preference 修复中,chosen 必须字面包含:嵌顿性腹股沟疝合并肠梗阻;rejected 不得是疾病名,只能写同一病例下的低质量处置。" - "腹股沟包块合并阶梯状液气平时,所有字段禁止出现穿孔、引流、推挤、减压等原文未给出的并发症或处置。" - "腹股沟包块合并肠梗阻风险时,CoT 的 final_answer 不得建议观察、延迟外科评估或延迟手术。" - ) - messages = [ - { - "role": "system", - "content": ( - f"你是严格的 JSON 修复器。只输出一个合法 JSON 对象,字段固定为 {fields}。" - "不要输出解释、markdown 或 。" - "只能基于原始输入和候选输出修复结构,不得编造原文不存在的诊断、症状或检查。" - "CoT 的 rationale 必须写成单个编号字符串,不得使用数组;必须包含六个编号:1. 2. 3. 4. 5. 6.;final_answer 必须存在且简短。" - "Preference 的 rejected 必须是同一病例下的低质量回答,不得用与病例性别或部位冲突的其他疾病凑数。" - "如果 Preference 候选 rejected 是离题疾病或其他诊断名称,必须改写为同病例低质量处置建议,例如仅建议观察、延误外科评估、忽视关键检查或遗漏高危证据。" - "如果 Preference 候选 chosen 是离题疾病或其他错误诊断,必须改写为原始输入支持的正确答案。" - f"{groin_repair_rules}" - "CoT 的 final_answer 必须是安全处置建议,不得输出明显错误的首要处理。" - f"{guardrail}" - ), - }, - { - "role": "user", - "content": ( - f"原始输入:{source_text}\n" - f"候选输出:{clipped}\n" - f"{note}\n" - "请修复为目标 JSON。" - ), - }, - ] - return self._render_native_chat_template(messages, enable_thinking=False) - return self.repair_templates[task_type].render(source_text=source_text, raw_output=clipped) - - def _build_repair_retry_note(self, task_type: str, source_text: str, raw_output: str) -> str: - source = source_text or "" - notes: List[str] = ["上一轮输出仍未通过质量校验,必须重写为合格 JSON。"] - if "腹股沟" in source and "阶梯状液气平" in source: - notes.append("删除所有字段中的禁用并发症或处置词,不要复述上一轮中的禁用表述。") - notes.append("CoT final_answer 只保留嵌顿性腹股沟疝合并肠梗阻和尽快外科评估。") - notes.append("Preference chosen 必须包含嵌顿性腹股沟疝合并肠梗阻,rejected 只能是同病例低质量处置。") - if raw_output: - notes.append("不要保留候选输出中触发上述问题的表达。") - return " ".join(notes) - - def _sanitize_failed_repair_output(self, source_text: str, raw_output: str) -> str: - sanitized = raw_output or "" - if "腹股沟" in (source_text or "") and "阶梯状液气平" in (source_text or ""): - sanitized = re.sub(r"避免延误导致[^。;;,,\"]+", "避免延误处理", sanitized) - sanitized = re.sub(r"防止[^。;;,,\"]+", "避免延误处理", sanitized) - sanitized = re.sub(r"(穿孔|肠穿孔|引流|推挤|减压)", "", sanitized) - if self._is_dka_source(source_text or ""): - sanitized = re.sub(r"(抗激素|神经系统受损原因|神经系统损伤|神经系统受损|碳酸氢钠|抗生素)", "", sanitized) - sanitized = re.sub(r"\binsulin\b", "", sanitized, flags=re.IGNORECASE) - sanitized = re.sub(r"依据\d+", "", sanitized) - if self._is_bacterial_pneumonia_source(source_text or ""): - sanitized = sanitized.replace("无呼吸道症状或无细菌证据", "忽视已有细菌感染证据") - sanitized = sanitized.replace("无呼吸道症状", "有呼吸道症状") - sanitized = sanitized.replace("无细菌证据", "忽视已有细菌感染证据") - sanitized = sanitized.replace("缺乏细菌感染证据", "忽视已有细菌感染证据") - return sanitized[:1800] - - def _render_second_repair_prompt(self, task_type: str, source_text: str, raw_output: str) -> str: - sanitized = self._sanitize_failed_repair_output(source_text, raw_output) - if self._qa_uses_native_template: - fields = "/".join(self.required_fields.get(task_type, [])) - guardrail = self._build_source_guardrail(source_text, task_type) - source = source_text or "" - groin_instruction = "" - if "腹股沟" in source and "阶梯状液气平" in source: - groin_instruction = "腹股沟包块合并阶梯状液气平时,诊断和处置只写:嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。" - content = ( - f"你是严格的 JSON 二次修复器。只输出一个合法 JSON 对象,字段固定为 {fields}。" - "请完全重写,不要沿用上一轮原句,不要输出解释、markdown 或 。" - "必须只根据原始输入和允许的医学结论生成,不能扩展原文未给出的并发症或处置。" - "CoT 的 rationale 必须写成单个编号字符串,不得使用数组;必须包含六个编号:1. 2. 3. 4. 5. 6.;final_answer 必须存在。" - f"{groin_instruction}" - f"{guardrail}" - ) - if task_type == "CoT": - user_content = ( - f"原始输入:{source_text}\n" - "上一轮候选输出结构不合格,已丢弃。请只基于原始输入重新生成目标 JSON。" - ) - else: - user_content = ( - f"原始输入:{source_text}\n" - f"上一轮失败输出(已清理禁用词):{sanitized}\n" - "请重新生成目标 JSON。" - ) - messages = [ - {"role": "system", "content": content}, - {"role": "user", "content": user_content}, - ] - return self._render_native_chat_template(messages, enable_thinking=False) - return self._render_repair_prompt(task_type, source_text, sanitized, self._build_repair_retry_note(task_type, source_text, sanitized)) - - def _normalize_parsed_data(self, task_type: str, data: Any) -> Optional[Dict[str, Any]]: - if not isinstance(data, dict): - return None - - allowed = self.required_fields.get(task_type, []) - if task_type == "QA" and "answer" not in data: - for alias in ["处理原则", "诊断", "结论", "回答", "answer_text"]: - if alias in data: - data = dict(data) - data["answer"] = data.get(alias) - break - normalized = {key: data.get(key) for key in allowed} - - if task_type == "CoT" and isinstance(normalized.get("rationale"), list): - normalized["rationale"] = "".join( - f"{i + 1}. {str(step).strip()}" - for i, step in enumerate(normalized["rationale"]) - if str(step).strip() - ) - elif task_type == "CoT" and isinstance(normalized.get("rationale"), str): - normalized["rationale"] = self._normalize_cot_rationale_text(normalized["rationale"]) - - return normalized - - def _normalize_cot_rationale_text(self, rationale: str) -> str: - text = re.sub(r"\s+", " ", rationale or "").strip() - if not text: - return text - if len(re.findall(r"(\d+[\.、]|步骤\d+|->)", text)) >= 3: - return text - - parts = [p.strip(" ;;。") for p in re.split(r"[。;;]", text) if p.strip(" ;;。")] - if len(parts) < 3: - comma_parts = [p.strip(" ,,") for p in re.split(r"[,,]", text) if p.strip(" ,,")] - if len(comma_parts) >= 4: - parts = comma_parts - - if len(parts) < 3: - return text - - steps = parts[:6] - return "".join(f"{i + 1}. {step}。" for i, step in enumerate(steps)) - - def _validate_generated_data( - self, - task_type: str, - data: Dict[str, Any], - source_text: Optional[str] = None, - ) -> bool: - required = self.required_fields.get(task_type, []) - if not required: - return False - if set(data.keys()) != set(required): - return False - for key in required: - value = data.get(key) - if value is None: - return False - if isinstance(value, str) and not value.strip(): - return False - return self._passes_task_quality(task_type, data, source_text) - - def _build_sampling_params(self, task_type: str) -> SamplingParams: - # 延迟优化策略:QA/Preference 限长提速;CoT 放宽长度获取更详细推理 - if task_type == "QA": - return SamplingParams( - temperature=0.0, - top_p=0.8, - max_tokens=220, - stop=["<|im_end|>"], - repetition_penalty=1.0, - ) - - if task_type == "Preference": - return SamplingParams( - temperature=0.0, - top_p=1.0, - max_tokens=320, - stop=["<|im_end|>"], - repetition_penalty=1.03, - structured_outputs=self._structured_json_params("Preference"), - ) - - # CoT:不刻意限短,保留较大 token 预算生成更长推理 - return SamplingParams( - temperature=0.0, - top_p=1.0, - max_tokens=900, - stop=["<|im_end|>"], - repetition_penalty=1.05, - structured_outputs=self._structured_json_params("CoT"), - ) - - def _build_repair_sampling_params(self, task_type: str) -> SamplingParams: - # 修复阶段使用更低随机性,优先稳定产出结构化 JSON - if task_type == "QA": - max_tokens = 220 - elif task_type == "CoT": - max_tokens = 1400 - else: - max_tokens = 360 - - return SamplingParams( - temperature=0.0, - top_p=0.9, - max_tokens=max_tokens, - stop=["<|im_end|>"], - repetition_penalty=1.0, - structured_outputs=self._structured_json_params(task_type) if task_type in ["CoT", "Preference"] else None, - ) - - def _structured_json_params(self, task_type: str) -> Any: - schema = self._json_schema_for_task(task_type) - if StructuredOutputsParams is not None: - return StructuredOutputsParams(json=schema, disable_any_whitespace=True) - return {"json": schema, "disable_any_whitespace": True} - - def _json_schema_for_task(self, task_type: str) -> Dict[str, Any]: - if task_type == "CoT": - return { - "type": "object", - "additionalProperties": False, - "required": ["question", "rationale", "final_answer"], - "properties": { - "question": {"type": "string", "minLength": 4, "maxLength": 220}, - "rationale": { - "type": "string", - "minLength": 40, - "maxLength": 900, - }, - "final_answer": {"type": "string", "minLength": 8, "maxLength": 220}, - }, - } - if task_type == "Preference": - return { - "type": "object", - "additionalProperties": False, - "required": ["question", "chosen", "rejected", "preference_reason"], - "properties": { - "question": {"type": "string", "minLength": 4, "maxLength": 220}, - "chosen": {"type": "string", "minLength": 8, "maxLength": 180}, - "rejected": {"type": "string", "minLength": 8, "maxLength": 180}, - "preference_reason": {"type": "string", "minLength": 12, "maxLength": 220}, - }, - } - raise ValueError(f"不支持的 task_type: {task_type}") - - def _truncate_text_at_boundary(self, text: str, limit: int) -> str: - value = text.strip() - if len(value) <= limit: - return value - - cut = value[:limit].rstrip() - - sentence_marks = "。!?.!?" - last_sentence = max(cut.rfind(mark) for mark in sentence_marks) - if last_sentence >= 20: - return cut[:last_sentence + 1].rstrip() - - phrase_marks = ";;,,、::" - last_phrase = max(cut.rfind(mark) for mark in phrase_marks) - if last_phrase >= 20: - return cut[:last_phrase].rstrip() - - last_space = cut.rfind(" ") - if last_space >= 20: - return cut[:last_space].rstrip(" ,;:") - - return cut.rstrip() - - def _truncate_qa_fields(self, data: Dict[str, Any]) -> Dict[str, Any]: - normalized = dict(data) - question = str(normalized.get("question", "")).strip() - answer = str(normalized.get("answer", "")).strip() - - q_limit = self.length_limits["QA"]["question"] - a_limit = self.length_limits["QA"]["answer"] - - normalized["question"] = self._truncate_text_at_boundary(question, q_limit) - normalized["answer"] = self._truncate_text_at_boundary(answer, a_limit) - - return normalized - - def _try_parse_and_validate( - self, - task_type: str, - text: str, - source_text: Optional[str] = None, - ) -> Optional[Dict[str, Any]]: - clean_text = self._clean_json_string(text) - candidates = [ - clean_text, - self._repair_json_syntax_only(clean_text), - clean_text.replace('\n', '\\n'), - self._repair_json_syntax_only(clean_text).replace('\n', '\\n'), - ] - - for candidate in candidates: - try: - data = json.loads(candidate, strict=False) - data = self._normalize_parsed_data(task_type, data) - if data is None: - continue - if task_type == "QA": - data = self._truncate_qa_fields(data) - if self._validate_generated_data(task_type, data, source_text): - return data - except Exception: - continue - return None - - def _repair_failed_batch(self, task_type: str, repair_items: List[Dict[str, Any]]) -> Dict[int, Dict[str, Any]]: - """ - 对首轮失败样本执行二阶段修复。 - repair_items: [{"idx": int, "source_text": str, "raw_output": str}, ...] - 返回: {idx: {"status": ..., "data": ...}} - """ - if not repair_items: - return {} - - prompts = [ - self._render_repair_prompt(task_type, item["source_text"], item.get("raw_output", "")) - for item in repair_items - ] - repair_outputs = self.llm.generate(prompts, self._build_repair_sampling_params(task_type)) - - repaired_result_map: Dict[int, Dict[str, Any]] = {} - retry_items: List[Dict[str, Any]] = [] - for item, output in zip(repair_items, repair_outputs): - idx = item["idx"] - repaired_text = output.outputs[0].text if output.outputs else "" - parsed = self._try_parse_and_validate(task_type, repaired_text, item["source_text"]) - if parsed is not None: - repaired_result_map[idx] = { - "status": "success", - "data": parsed, - "repaired": True, - } - continue - - retry_items.append({ - "idx": idx, - "source_text": item["source_text"], - "raw_output": item.get("raw_output", ""), - "repair_raw_output": repaired_text, - }) - - if retry_items: - retry_prompts = [ - self._render_second_repair_prompt(task_type, item["source_text"], item.get("repair_raw_output", "")) - for item in retry_items - ] - retry_outputs = self.llm.generate(retry_prompts, self._build_repair_sampling_params(task_type)) - - for item, output in zip(retry_items, retry_outputs): - idx = item["idx"] - retry_text = output.outputs[0].text if output.outputs else "" - parsed = self._try_parse_and_validate(task_type, retry_text, item["source_text"]) - if parsed is not None: - repaired_result_map[idx] = { - "status": "success", - "data": parsed, - "repaired": True, - "repair_attempts": 2, - } - continue - - repaired_result_map[idx] = { - "status": "failed", - "reason": "repair_failed", - "raw_output": item.get("raw_output", ""), - "repair_raw_output": item.get("repair_raw_output", ""), - "second_repair_raw_output": retry_text, - } - - for item in retry_items: - idx = item["idx"] - if idx in repaired_result_map: - continue - repaired_result_map[idx] = { - "status": "failed", - "reason": "repair_failed", - "raw_output": item.get("raw_output", ""), - "repair_raw_output": item.get("repair_raw_output", ""), - } - - return repaired_result_map - - def generate_data_batch(self, task_type: str, inputs: List[str]) -> List[Dict[str, Any]]: - if task_type not in self.task_templates: - raise ValueError(f"不支持的 task_type: {task_type}") - - prompts = [] - for text in inputs: - prompts.append(self._render_prompt(task_type, text)) - - sampling_params = self._build_sampling_params(task_type) - - outputs = self.llm.generate(prompts, sampling_params) - - # 先占位,首轮失败的样本进入二阶段修复 - results: List[Optional[Dict[str, Any]]] = [None] * len(outputs) - repair_items: List[Dict[str, Any]] = [] - - for i, output in enumerate(outputs): - generated_text = output.outputs[0].text if output.outputs else "" - parsed = self._try_parse_and_validate(task_type, generated_text, inputs[i]) - if parsed is not None: - results[i] = {"status": "success", "data": parsed} - continue - - # 首轮直接失败,进入修复阶段 - repair_items.append({ - "idx": i, - "source_text": inputs[i], - "raw_output": generated_text, - }) - - repaired_map = self._repair_failed_batch(task_type, repair_items) - for item in repair_items: - idx = item["idx"] - if idx in repaired_map: - results[idx] = repaired_map[idx] - else: - results[idx] = { - "status": "failed", - "reason": "repair_missing", - "raw_output": item.get("raw_output", ""), - } - - # 理论上不应存在 None,这里兜底 - for i, r in enumerate(results): - if r is None: - results[i] = { - "status": "failed", - "reason": "internal_empty_result", - "raw_output": "", - } - - - return [r for r in results if r is not None] - - def _extract_case_parts(self, source_text: str) -> Dict[str, str]: - demo = "" - symptom = "" - finding = "" - - m_demo = re.search(r"^(.*?)。主诉[::]", source_text) - if m_demo: - demo = m_demo.group(1).strip() - - m_symptom = re.search(r"主诉[::](.*?)。查体", source_text) - if m_symptom: - symptom = m_symptom.group(1).strip() - - m_finding = re.search(r"查体及辅助检查[::](.*?)(。|$)", source_text) - if m_finding: - finding = m_finding.group(1).strip() - - if not demo and not symptom and not finding: - return { - "demo": "患者", - "symptom": source_text.strip()[:60], - "finding": "检查信息待补充", - } - - return { - "demo": demo or "患者", - "symptom": symptom or "症状待补充", - "finding": finding or "检查信息待补充", - } - - def _infer_primary_assessment(self, finding: str) -> str: - f = finding or "" - if "ST段抬高" in f: - return "急性冠脉综合征风险" - if "脑梗死" in f: - return "脑梗死相关神经功能受损" - if "斑片影" in f: - return "肺部炎症性病变" - if "结石" in f: - return "结石相关器官病变" - if "尿蛋白" in f: - return "肾脏受损风险" - if "白细胞升高" in f or "CRP升高" in f: - return "感染或炎症反应" - return "临床异常需进一步评估" - -if __name__ == "__main__": - pass diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/requirement_metrics.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/requirement_metrics.py deleted file mode 100644 index 11922e1e..00000000 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/requirement_metrics.py +++ /dev/null @@ -1,83 +0,0 @@ -from __future__ import annotations - -from typing import Dict, List, Any, Iterable - - -REQUIRED_FIELDS = { - "QA": ["question", "answer"], - "CoT": ["question", "rationale", "final_answer"], - "Preference": ["question", "chosen", "rejected", "preference_reason"], -} - - -def _safe_mean(values: Iterable[float]) -> float: - values = list(values) - return sum(values) / len(values) if values else 0.0 - - -def _field_complete(item: Dict[str, Any], task_type: str) -> bool: - required = REQUIRED_FIELDS.get(task_type, []) - for key in required: - v = item.get(key) - if v is None: - return False - if isinstance(v, str) and not v.strip(): - return False - return True - - -def calculate_generation_metrics( - records: List[Dict[str, Any]], - evaluator_scores: List[Dict[str, Any]], -) -> Dict[str, float]: - """ - records: [{task_type, status, latency, data:{...}}] - evaluator_scores: [{scores:{维度:{score:int}}}] - """ - avg_latency = _safe_mean(r.get("latency", 0.0) for r in records) - - format_integrity = _safe_mean( - 1.0 if (r.get("status") == "success" and _field_complete(r.get("data", {}), r.get("task_type", ""))) else 0.0 - for r in records - ) * 100 - - # 多样性口径:成功样本中的唯一 question 数 - questions = [ - r.get("data", {}).get("question", "").strip() - for r in records - if r.get("status") == "success" - ] - diversity_count = len({q for q in questions if q}) - - def dim_rate(dim: str) -> float: - valid = [] - for item in evaluator_scores: - score = item.get("scores", {}).get(dim, {}).get("score", -1) - if isinstance(score, int) and score >= 0: - valid.append(1.0 if score == 1 else 0.0) - return _safe_mean(valid) * 100 - - metrics = { - "avg_latency_sec": avg_latency, - "format_integrity_pct": format_integrity, - "accuracy_pct": dim_rate("准确性"), - "relevance_pct": dim_rate("相关性"), - "safety_pct": dim_rate("安全性"), - "diversity_pct": dim_rate("多样性"), - "completeness_pct": dim_rate("完整性"), - "diversity_count": float(diversity_count), - } - return metrics - - -def check_project_targets(metrics: Dict[str, float]) -> Dict[str, bool]: - """按需求阈值判断是否达标。""" - return { - "latency_ok": metrics.get("avg_latency_sec", 999) <= 3.0, - "accuracy_ok": metrics.get("accuracy_pct", 0) >= 90.0, - "relevance_ok": metrics.get("relevance_pct", 0) >= 95.0, - "safety_ok": metrics.get("safety_pct", 0) >= 95.0, - "diversity_ok": metrics.get("diversity_pct", 0) >= 85.0, - "completeness_ok": metrics.get("completeness_pct", 0) >= 85.0, - "format_integrity_ok": metrics.get("format_integrity_pct", 0) >= 100.0, - } diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/test_evaluator_backend.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/test_evaluator_backend.py deleted file mode 100644 index 02e47c91..00000000 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis/test_evaluator_backend.py +++ /dev/null @@ -1,110 +0,0 @@ -import json -import os -import sys -import unittest - - -CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) -if CURRENT_DIR not in sys.path: - sys.path.insert(0, CURRENT_DIR) - -from data_evaluator import MedicalDataEvaluator - - -class _FakeCandidate: - def __init__(self, text): - self.text = text - - -class _FakeResult: - def __init__(self, text): - self.outputs = [_FakeCandidate(text)] - - -class EvaluatorBackendTests(unittest.TestCase): - def test_vllm_backend_calls_llm_generate(self): - class CountingLLM: - def __init__(self): - self.calls = 0 - self.prompt_count = 0 - self.prompts = [] - - def generate(self, prompts, sampling_params): - self.calls += 1 - self.prompt_count += len(prompts) - self.prompts.extend(prompts) - return [ - _FakeResult(json.dumps({"score": 1, "reason": "model judged pass"})) - for _ in prompts - ] - - llm = CountingLLM() - evaluator = MedicalDataEvaluator( - model_path=None, - llm_instance=llm, - backend="vllm", - ) - dimension = next(iter(evaluator.dimension_criteria)) - - results = evaluator.evaluate( - [{"id": 1, "type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}], - target_dimensions=[dimension], - ) - - self.assertEqual(llm.calls, 1) - self.assertEqual(llm.prompt_count, 1) - self.assertIn('"sample_type": "QA"', llm.prompts[0]) - self.assertIn('"question": "q"', llm.prompts[0]) - self.assertIn('"answer": "a"', llm.prompts[0]) - self.assertIn('"question_present": true', llm.prompts[0]) - self.assertIn('"answer_present": true', llm.prompts[0]) - self.assertIn("禁止把该字段判定为空", llm.prompts[0]) - self.assertNotIn('"rationale"', llm.prompts[0]) - self.assertNotIn('"raw_content"', llm.prompts[0]) - self.assertEqual(results[0]["scores"][dimension]["score"], 1) - - def test_rule_backend_does_not_call_llm_generate(self): - class FailingLLM: - def generate(self, prompts, sampling_params): - raise AssertionError("rule backend must not call LLM.generate") - - evaluator = MedicalDataEvaluator( - model_path=None, - llm_instance=FailingLLM(), - backend="rule", - ) - dimension = next(iter(evaluator.dimension_criteria)) - - results = evaluator.evaluate( - [{"id": 1, "type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}], - target_dimensions=[dimension], - ) - - self.assertIn(dimension, results[0]["scores"]) - - def test_vllm_backend_corrects_obvious_empty_field_misread(self): - class EmptyFieldMisreadLLM: - def generate(self, prompts, sampling_params): - return [ - _FakeResult(json.dumps({"score": 0, "reason": "问题和答案字段内容为空"})) - for _ in prompts - ] - - evaluator = MedicalDataEvaluator( - model_path=None, - llm_instance=EmptyFieldMisreadLLM(), - backend="vllm", - ) - dimension = next(iter(evaluator.dimension_criteria)) - - results = evaluator.evaluate( - [{"id": 1, "type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}], - target_dimensions=[dimension], - ) - - self.assertEqual(results[0]["scores"][dimension]["score"], 1) - self.assertIn("llm_consistency_corrected", results[0]["scores"][dimension]["reason"]) - - -if __name__ == "__main__": - unittest.main() diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/Dockerfile b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/Dockerfile deleted file mode 100644 index 76a0f760..00000000 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/Dockerfile +++ /dev/null @@ -1,18 +0,0 @@ -ARG BASE_IMAGE=quay.io/ascend/vllm-ascend:v0.18.0rc1 -FROM ${BASE_IMAGE} - -WORKDIR /app - -COPY data_synthesis_service/requirements-base.txt /tmp/requirements-base.txt -COPY data_synthesis_service/requirements.txt /tmp/requirements.txt -COPY data_synthesis_service/requirements-npu.txt /tmp/requirements-npu.txt -ARG REQUIREMENTS_FILE=requirements.txt -RUN python -m pip install --no-cache-dir --no-deps -r /tmp/${REQUIREMENTS_FILE} - -COPY data_synthesis /app/data_synthesis -COPY data_synthesis_service /app/data_synthesis_service - -ENV PYTHONPATH=/app -EXPOSE 18080 - -CMD ["bash", "-lc", "set -e; unset ASCEND_LAUNCH_BLOCKING; export HCCL_OP_EXPANSION_MODE=AIV; source /usr/local/Ascend/ascend-toolkit/set_env.sh; exec python -m uvicorn data_synthesis_service.app:app --host 0.0.0.0 --port 18080"] diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/README.md b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/README.md deleted file mode 100644 index 07c125f4..00000000 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# data_synthesis_service 服务补丁 - -本目录归档独立 HTTP 服务中与数据质量评估相关的代码。 - -## 接口 - -- `GET /health` -- `POST /synthesize-file` -- `POST /evaluate-file` - -## 本地启动示例 - -```bash -python -m uvicorn data_synthesis_service.app:app --host 0.0.0.0 --port 18080 -``` - -## 依赖 - -- `requirements.txt` 是独立服务生产依赖,完全对标 910b-jss 已验证镜像 `huizhi:test-v018`。 -- 基础镜像固定为 `quay.io/ascend/vllm-ascend:v0.18.0rc1`,对应 Python `3.11.14`、CANN `8.5.1`。 -- 关键版本包括 `vllm==0.18.0+empty`、`vllm_ascend==0.18.0rc1`、`torch==2.9.0+cpu`、`torch_npu==2.9.0.post1+gitee7ba04`。 -- `requirements-base.txt` 只用于无模型接口冒烟测试。 -- `requirements-npu.txt` 是兼容旧文档的别名,等价引用 `requirements.txt`。 -- DataMate 算子本体依赖在 `operator_src/requirements.txt`,不应安装 vLLM。 - -正式 NPU 构建示例: - -```bash -docker build -t data-synthesis-service:latest \ - -f data_synthesis_service/Dockerfile . -``` - -不传构建参数时默认使用 910b-jss 对标基础镜像并安装 `requirements.txt`。无模型接口冒烟测试可显式增加 `--build-arg REQUIREMENTS_FILE=requirements-base.txt`。 - -Dockerfile 使用 `pip install --no-deps`。这是为了保留 `quay.io/ascend/vllm-ascend:v0.18.0rc1` 中已经验证的 vLLM-Ascend 依赖闭包,避免 pip 重新解析传递依赖导致版本漂移。 - -## 模型路径 - -启动服务前通过环境变量指定容器内模型路径: - -- `DATA_SYNTHESIS_MODEL_PATH` -- `DATA_EVALUATOR_MODEL_PATH` - -默认模型挂载点为容器内 `/model`。 - -路径说明: - -- `data_synthesis_service/` 与 `data_synthesis/` 是构建上下文中的相对源码目录。 -- `/model` 是服务容器内模型挂载点,不是主机固定路径;主机模型目录由 Docker `-v` 参数挂载。 -- `/tmp/requirements*.txt` 是 Dockerfile 构建阶段临时依赖文件路径。 -- `/usr/local/Ascend/...` 是 vLLM-Ascend 基础镜像和宿主机驱动的容器内标准路径;非标准镜像需要提供等价路径。 diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/__init__.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/__init__.py deleted file mode 100644 index dee6f9b5..00000000 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .app import app, create_app -from .core import SynthesisService - -__all__ = ["app", "create_app", "SynthesisService"] diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/core.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/core.py deleted file mode 100644 index 2ec510b1..00000000 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/core.py +++ /dev/null @@ -1,607 +0,0 @@ -import json -import os -import subprocess -import sys -import time -from dataclasses import dataclass -from typing import Any, Dict, Iterable, List, Optional - - -CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) -PROJECT_ROOT = os.path.dirname(CURRENT_DIR) -DATA_SYNTHESIS_DIR = os.path.join(PROJECT_ROOT, "data_synthesis") -if DATA_SYNTHESIS_DIR not in sys.path: - sys.path.insert(0, DATA_SYNTHESIS_DIR) - -from data_evaluator import MedicalDataEvaluator -from data_synthesizer import MedicalDataSynthesizer -from requirement_metrics import calculate_generation_metrics, check_project_targets - - -SUPPORTED_TASK_TYPES = ("QA", "CoT", "Preference") -DEFAULT_EVALUATION_DIMENSIONS = ("准确性", "相关性", "安全性", "多样性", "完整性") -DEFAULT_EVALUATOR_MODEL_PATH = "/model/Qwen/Qwen2.5-7B-Instruct" - - -@dataclass -class _GeneratedCandidate: - text: str - - -@dataclass -class _GeneratedResult: - outputs: List[_GeneratedCandidate] - - -class TransformersLLMAdapter: - def __init__(self, model_path: str) -> None: - try: - import torch - from transformers import AutoModelForCausalLM, AutoTokenizer - except Exception as exc: # pragma: no cover - raise ImportError(f"transformers backend unavailable: {exc}") from exc - - self._torch = torch - self._device = "cpu" - model_dtype = torch.float32 - try: - import torch_npu # noqa: F401 - - if hasattr(torch, "npu") and torch.npu.is_available(): - self._device = "npu:0" - model_dtype = torch.float16 - except Exception: - self._device = "cpu" - - self._tokenizer = AutoTokenizer.from_pretrained( - model_path, - trust_remote_code=True, - ) - self._model = AutoModelForCausalLM.from_pretrained( - model_path, - trust_remote_code=True, - torch_dtype=model_dtype, - ) - if self._device != "cpu": - self._model = self._model.to(self._device) - - self._model.eval() - - def generate(self, prompts: List[str], sampling_params: Any) -> List[_GeneratedResult]: - max_new_tokens = int(getattr(sampling_params, "kwargs", {}).get("max_tokens", 256)) - temperature = float(getattr(sampling_params, "kwargs", {}).get("temperature", 0.1)) - top_p = float(getattr(sampling_params, "kwargs", {}).get("top_p", 0.9)) - repetition_penalty = float(getattr(sampling_params, "kwargs", {}).get("repetition_penalty", 1.0)) - - outputs: List[_GeneratedResult] = [] - for prompt in prompts: - model_inputs = self._tokenizer(prompt, return_tensors="pt") - if self._device != "cpu": - model_inputs = {k: v.to(self._device) for k, v in model_inputs.items()} - - with self._torch.no_grad(): - generated_ids = self._model.generate( - **model_inputs, - do_sample=temperature > 0, - temperature=max(temperature, 1e-5), - top_p=top_p, - repetition_penalty=repetition_penalty, - max_new_tokens=max_new_tokens, - pad_token_id=self._tokenizer.eos_token_id, - ) - - prompt_len = model_inputs["input_ids"].shape[1] - new_tokens = generated_ids[0][prompt_len:] - text = self._tokenizer.decode(new_tokens, skip_special_tokens=False) - outputs.append(_GeneratedResult(outputs=[_GeneratedCandidate(text=text)])) - return outputs - - -def _normalize_task_types(task_types: Optional[Iterable[str]]) -> List[str]: - if task_types is None: - return list(SUPPORTED_TASK_TYPES) - normalized = [task_type.strip() for task_type in task_types if str(task_type).strip()] - invalid = [task_type for task_type in normalized if task_type not in SUPPORTED_TASK_TYPES] - if invalid: - raise ValueError(f"Unsupported task_types: {invalid}") - if not normalized: - raise ValueError("task_types must not be empty") - return normalized - - -def _normalize_dimensions(target_dimensions: Optional[Iterable[str]]) -> List[str]: - if target_dimensions is None: - return list(DEFAULT_EVALUATION_DIMENSIONS) - normalized = [str(dim).strip() for dim in target_dimensions if str(dim).strip()] - invalid = [dim for dim in normalized if dim not in DEFAULT_EVALUATION_DIMENSIONS] - if invalid: - raise ValueError(f"Unsupported target_dimensions: {invalid}") - if not normalized: - raise ValueError("target_dimensions must not be empty") - return normalized - - -def _make_record(record_id: int, task_type: str, payload: Dict[str, Any]) -> Dict[str, Any]: - return { - "id": record_id, - "type": task_type, - "content": json.dumps(payload, ensure_ascii=False), - } - - -def _records_from_synthesis_payload(payload: Dict[str, Any]) -> List[Dict[str, Any]]: - records: List[Dict[str, Any]] = [] - next_id = 1 - results = payload.get("results", {}) - if not isinstance(results, dict): - return records - - for task_type in SUPPORTED_TASK_TYPES: - items = results.get(task_type, []) - if not isinstance(items, list): - continue - for item in items: - data = item - if isinstance(item, dict) and "data" in item: - if item.get("status") != "success": - continue - data = item.get("data", {}) - if not isinstance(data, dict): - continue - records.append(_make_record(next_id, task_type, data)) - next_id += 1 - return records - - -def _parse_evaluation_input(text: str) -> List[Dict[str, Any]]: - raw = (text or "").strip() - if not raw: - raise ValueError("text must not be empty") - - try: - parsed = json.loads(raw) - except json.JSONDecodeError as exc: - raise ValueError("evaluation input must be JSON text") from exc - - if isinstance(parsed, dict) and "results" in parsed: - records = _records_from_synthesis_payload(parsed) - if records: - return records - raise ValueError("No successful generated records found in synthesis results") - - if isinstance(parsed, dict) and isinstance(parsed.get("records"), list): - parsed = parsed["records"] - - if isinstance(parsed, dict) and "content" in parsed: - parsed = [parsed] - - if not isinstance(parsed, list): - raise ValueError("evaluation input must be a JSON array, a record object, or synthesis results JSON") - - records: List[Dict[str, Any]] = [] - for idx, item in enumerate(parsed, start=1): - if not isinstance(item, dict): - raise ValueError("Each evaluation record must be a JSON object") - content = item.get("content") - if isinstance(content, dict): - task_type = str(item.get("type") or "QA") - records.append(_make_record(int(item.get("id") or idx), task_type, content)) - continue - if not isinstance(content, str) or not content.strip(): - raise ValueError("Each evaluation record must contain non-empty content") - records.append( - { - "id": int(item.get("id") or idx), - "type": str(item.get("type") or "QA"), - "content": content, - } - ) - - if not records: - raise ValueError("No evaluation records found") - return records - - -class SynthesisService: - def __init__( - self, - model_path: Optional[str] = None, - evaluator_model_path: Optional[str] = None, - synthesizer: Any = None, - evaluator: Any = None, - ) -> None: - self.model_path = model_path or os.environ.get("DATA_SYNTHESIS_MODEL_PATH") or os.environ.get("MODEL_PATH") - self.evaluator_model_path = ( - evaluator_model_path - or os.environ.get("DATA_EVALUATOR_MODEL_PATH") - or DEFAULT_EVALUATOR_MODEL_PATH - ) - self.backend = os.environ.get("DATA_SYNTHESIS_BACKEND", "auto").lower() - self.run_mode = os.environ.get("DATA_SYNTHESIS_RUN_MODE", "inprocess").lower() - self._ready = False - self._init_error: Optional[str] = "Service not initialized" - self._synthesizer_error: Optional[str] = None - self._evaluator_error: Optional[str] = None - self.synthesizer = synthesizer - self.evaluator = evaluator - self.evaluator_backend = ( - os.environ.get("DATA_EVALUATOR_BACKEND") - or "vllm" - ).strip().lower() - - def _initialize_components(self) -> None: - try: - self.synthesizer = self.synthesizer or self._build_synthesizer() - self._ready = True - self._init_error = None - except Exception as exc: - self._ready = False - self._init_error = str(exc) - - def _ensure_synthesizer_initialized(self) -> None: - if self.synthesizer is not None: - self._ready = True - self._init_error = None - return - try: - self.synthesizer = self._build_synthesizer() - self._ready = True - self._init_error = None - self._synthesizer_error = None - except Exception as exc: - self._ready = False - self._init_error = str(exc) - self._synthesizer_error = str(exc) - - def _ensure_evaluator_initialized(self, backend: Optional[str] = None) -> None: - requested_backend = (backend or self.evaluator_backend or "vllm").strip().lower() - current_backend = getattr(self.evaluator, "backend", None) - if self.evaluator is not None and current_backend in (None, requested_backend): - self._evaluator_error = None - return - try: - self.evaluator = MedicalDataEvaluator( - self.evaluator_model_path, - backend=requested_backend, - ) - self._evaluator_error = None - except Exception as exc: - self._evaluator_error = str(exc) - raise - - def _ensure_initialized(self) -> None: - if self._ready and self.synthesizer is not None: - return - self._ensure_synthesizer_initialized() - if not self._ready: - self._ensure_synthesizer_initialized() - - def health(self) -> Dict[str, Any]: - if self.run_mode != "subprocess": - self._ensure_initialized() - return { - "service": "data_synthesis", - "ready": True if self.run_mode == "subprocess" else self._ready, - "model_path": self.model_path, - "evaluator_model_path": self.evaluator_model_path, - "backend": self.backend, - "evaluator_backend": self.evaluator_backend, - "error": None if self.run_mode == "subprocess" else self._init_error, - } - - def _build_synthesizer(self) -> MedicalDataSynthesizer: - if not self.model_path: - raise ValueError("model_path is required") - - if self.backend == "transformers": - return MedicalDataSynthesizer( - self.model_path, - llm_instance=TransformersLLMAdapter(self.model_path), - ) - - if self.backend == "vllm": - return MedicalDataSynthesizer(self.model_path) - - try: - return MedicalDataSynthesizer(self.model_path) - except Exception: - return MedicalDataSynthesizer( - self.model_path, - llm_instance=TransformersLLMAdapter(self.model_path), - ) - - def synthesize_text( - self, - file_name: str, - text: str, - task_types: Optional[Iterable[str]] = None, - include_metrics: bool = True, - ) -> Dict[str, Any]: - if self.run_mode == "subprocess": - return self._synthesize_via_subprocess( - file_name=file_name, - text=text, - task_types=task_types, - include_metrics=include_metrics, - ) - - self._ensure_initialized() - if not self._ready or self.synthesizer is None: - raise RuntimeError(self._init_error or "Service is not ready") - - normalized_text = (text or "").strip() - if not normalized_text: - raise ValueError("text must not be empty") - - normalized_task_types = _normalize_task_types(task_types) - results: Dict[str, List[Dict[str, Any]]] = {task_type: [] for task_type in SUPPORTED_TASK_TYPES} - records: List[Dict[str, Any]] = [] - evaluation_inputs: List[Dict[str, Any]] = [] - - for task_type in normalized_task_types: - started_at = time.time() - batch_results = self.synthesizer.generate_data_batch(task_type, [normalized_text]) - elapsed = time.time() - started_at - per_item_latency = elapsed / max(len(batch_results), 1) - results[task_type] = batch_results - - for item in batch_results: - record = { - "task_type": task_type, - "status": item.get("status", "failed"), - "latency": per_item_latency, - "data": item.get("data", {}), - } - records.append(record) - if item.get("status") == "success": - evaluation_inputs.append( - { - "type": task_type, - "content": json.dumps(item.get("data", {}), ensure_ascii=False), - } - ) - - metrics: Dict[str, Any] = {} - if include_metrics: - metrics = self._build_metrics(records, evaluation_inputs) - - return { - "source_file": file_name, - "task_types": normalized_task_types, - "results": results, - "metrics": metrics, - "status": "success", - } - - def evaluate_text( - self, - file_name: str, - text: str, - target_dimensions: Optional[Iterable[str]] = None, - include_summary: bool = True, - model_path: Optional[str] = None, - backend: Optional[str] = None, - ) -> Dict[str, Any]: - if self.run_mode == "subprocess": - return self._evaluate_via_subprocess( - file_name=file_name, - text=text, - target_dimensions=target_dimensions, - include_summary=include_summary, - model_path=model_path, - backend=backend, - ) - - if model_path and model_path != self.evaluator_model_path: - self.evaluator_model_path = model_path - self.evaluator = None - try: - self._ensure_evaluator_initialized(backend or self.evaluator_backend or "vllm") - except Exception as exc: - raise RuntimeError(str(exc)) from exc - if self.evaluator is None: - raise RuntimeError(self._init_error or "Evaluator is not ready") - - records = _parse_evaluation_input(text) - dimensions = _normalize_dimensions(target_dimensions) - evaluation_results = self.evaluator.evaluate(records, target_dimensions=dimensions) - - response: Dict[str, Any] = { - "source_file": file_name, - "record_count": len(records), - "dimensions": dimensions, - "results": evaluation_results, - "runtime": ( - self.evaluator.runtime_metadata() - if hasattr(self.evaluator, "runtime_metadata") - else { - "evaluator_backend": getattr(self.evaluator, "backend", "unknown"), - "evaluator_model_path": self.evaluator_model_path, - "vllm_enabled": getattr(self.evaluator, "backend", None) == "vllm", - } - ), - "status": "success", - } - if include_summary: - response["summary"] = self._build_evaluation_summary(records, evaluation_results, dimensions) - return response - - def _synthesize_via_subprocess( - self, - file_name: str, - text: str, - task_types: Optional[Iterable[str]], - include_metrics: bool, - ) -> Dict[str, Any]: - normalized_task_types = _normalize_task_types(task_types) - worker_payload = { - "file_name": file_name, - "text": text, - "task_types": normalized_task_types, - "include_metrics": include_metrics, - "model_path": self.model_path, - "backend": self.backend, - } - worker_code = """ -import json -import os -import sys -payload = json.loads(sys.stdin.read()) -os.environ["DATA_SYNTHESIS_MODEL_PATH"] = payload["model_path"] or "" -os.environ["DATA_SYNTHESIS_BACKEND"] = payload["backend"] -from data_synthesis_service.core import SynthesisService -service = SynthesisService(model_path=payload["model_path"]) -result = service.synthesize_text( - file_name=payload["file_name"], - text=payload["text"], - task_types=payload["task_types"], - include_metrics=payload["include_metrics"], -) -print(json.dumps(result, ensure_ascii=False)) -""" - env = os.environ.copy() - env["DATA_SYNTHESIS_RUN_MODE"] = "inprocess" - completed = subprocess.run( - [sys.executable, "-c", worker_code], - input=json.dumps(worker_payload, ensure_ascii=False), - text=True, - capture_output=True, - env=env, - cwd=PROJECT_ROOT, - check=False, - ) - if completed.returncode != 0: - error_text = (completed.stderr or completed.stdout or "subprocess failed").strip() - raise RuntimeError(error_text) - output_lines = [line.strip() for line in completed.stdout.splitlines() if line.strip()] - if not output_lines: - raise RuntimeError("subprocess returned empty output") - return json.loads(output_lines[-1]) - - def _evaluate_via_subprocess( - self, - file_name: str, - text: str, - target_dimensions: Optional[Iterable[str]], - include_summary: bool, - model_path: Optional[str], - backend: Optional[str] = None, - ) -> Dict[str, Any]: - normalized_dimensions = _normalize_dimensions(target_dimensions) - worker_payload = { - "action": "evaluate", - "file_name": file_name, - "text": text, - "target_dimensions": normalized_dimensions, - "include_summary": include_summary, - "model_path": model_path or self.evaluator_model_path, - "synthesis_model_path": self.model_path, - "backend": self.backend, - "evaluator_backend": backend or self.evaluator_backend or "vllm", - } - return self._run_subprocess_worker(worker_payload) - - def _run_subprocess_worker(self, worker_payload: Dict[str, Any]) -> Dict[str, Any]: - worker_code = """ -import json -import os -import sys -payload = json.loads(sys.stdin.read()) -os.environ["DATA_SYNTHESIS_MODEL_PATH"] = payload.get("synthesis_model_path") or payload.get("model_path") or "" -os.environ["DATA_EVALUATOR_MODEL_PATH"] = payload.get("model_path") or "" -os.environ["DATA_SYNTHESIS_BACKEND"] = payload.get("backend") or "auto" -os.environ["DATA_EVALUATOR_BACKEND"] = payload.get("evaluator_backend") or "vllm" -from data_synthesis_service.core import SynthesisService -service = SynthesisService( - model_path=payload.get("synthesis_model_path"), - evaluator_model_path=payload.get("model_path"), -) -action = payload.get("action") -if action == "synthesize": - result = service.synthesize_text( - file_name=payload["file_name"], - text=payload["text"], - task_types=payload["task_types"], - include_metrics=payload["include_metrics"], - ) -elif action == "evaluate": - result = service.evaluate_text( - file_name=payload["file_name"], - text=payload["text"], - target_dimensions=payload["target_dimensions"], - include_summary=payload["include_summary"], - model_path=payload.get("model_path"), - backend=payload.get("evaluator_backend"), - ) -else: - raise RuntimeError(f"Unsupported action: {action}") -print(json.dumps(result, ensure_ascii=False)) -""" - env = os.environ.copy() - env["DATA_SYNTHESIS_RUN_MODE"] = "inprocess" - completed = subprocess.run( - [sys.executable, "-c", worker_code], - input=json.dumps(worker_payload, ensure_ascii=False), - text=True, - capture_output=True, - env=env, - cwd=PROJECT_ROOT, - check=False, - ) - if completed.returncode != 0: - error_text = (completed.stderr or completed.stdout or "subprocess failed").strip() - raise RuntimeError(error_text) - output_lines = [line.strip() for line in completed.stdout.splitlines() if line.strip()] - if not output_lines: - raise RuntimeError("subprocess returned empty output") - return json.loads(output_lines[-1]) - - def _build_metrics( - self, - records: List[Dict[str, Any]], - evaluation_inputs: List[Dict[str, Any]], - ) -> Dict[str, Any]: - try: - self._ensure_evaluator_initialized("rule") - evaluator_scores = self.evaluator.evaluate(evaluation_inputs) if evaluation_inputs else [] - summary = calculate_generation_metrics(records, evaluator_scores) - return { - "ready": True, - "summary": summary, - "targets": check_project_targets(summary), - } - except Exception as exc: - return {"ready": False, "error": str(exc)} - - def _build_evaluation_summary( - self, - records: List[Dict[str, Any]], - evaluation_results: List[Dict[str, Any]], - dimensions: List[str], - ) -> Dict[str, Any]: - per_dimension: Dict[str, Dict[str, Any]] = {} - for dim in dimensions: - scores = [] - for item in evaluation_results: - score = item.get("scores", {}).get(dim, {}).get("score", -1) - if isinstance(score, int) and score >= 0: - scores.append(score) - pass_count = sum(1 for score in scores if score == 1) - total = len(scores) - pass_rate = (pass_count / total * 100.0) if total else 0.0 - per_dimension[dim] = { - "pass_count": pass_count, - "total": total, - "pass_rate_pct": pass_rate, - } - - task_type_counts: Dict[str, int] = {} - for record in records: - task_type = str(record.get("type") or "QA") - task_type_counts[task_type] = task_type_counts.get(task_type, 0) + 1 - - return { - "record_count": len(records), - "task_type_counts": task_type_counts, - "dimensions": per_dimension, - } diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements-base.txt b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements-base.txt deleted file mode 100644 index 29ad47ad..00000000 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements-base.txt +++ /dev/null @@ -1,7 +0,0 @@ -# HTTP service base dependencies for smoke tests without model inference. -# Versions are aligned with 910b-jss huizhi:test-v018. -fastapi==0.123.10 -uvicorn==0.42.0 -pydantic==2.12.5 -Jinja2==3.1.6 -requests==2.33.1 diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements-npu.txt b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements-npu.txt deleted file mode 100644 index 626e52fe..00000000 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements-npu.txt +++ /dev/null @@ -1,2 +0,0 @@ -# Backward-compatible alias for the full NPU/vLLM service dependencies. --r requirements.txt diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements.txt b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements.txt deleted file mode 100644 index b65dd8c1..00000000 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/requirements.txt +++ /dev/null @@ -1,20 +0,0 @@ -# Independent service production dependencies aligned with 910b-jss huizhi:test-v018. -# Base image: quay.io/ascend/vllm-ascend:v0.18.0rc1 -# Python: 3.11.14, CANN: 8.5.1 -# Do not put these into the DataMate operator_src/requirements.txt. -fastapi==0.123.10 -uvicorn==0.42.0 -pydantic==2.12.5 -Jinja2==3.1.6 -requests==2.33.1 -vllm==0.18.0+empty -vllm_ascend==0.18.0rc1 -torch==2.9.0+cpu -torch_npu==2.9.0.post1+gitee7ba04 -transformers==4.57.6 -tokenizers==0.22.2 -sentencepiece==0.2.1 -einops==0.8.2 -numpy==1.26.4 -safetensors==0.7.0 -typing_extensions==4.15.0 diff --git a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/tests/test_evaluator_backend_service.py b/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/tests/test_evaluator_backend_service.py deleted file mode 100644 index a8beae25..00000000 --- a/runtime/ops/mapper/data_quality_evaluator/service_patch/data_synthesis_service/tests/test_evaluator_backend_service.py +++ /dev/null @@ -1,76 +0,0 @@ -import json -import os -import sys -import unittest -from unittest.mock import patch - - -CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) -PROJECT_ROOT = os.path.dirname(os.path.dirname(CURRENT_DIR)) -if PROJECT_ROOT not in sys.path: - sys.path.insert(0, PROJECT_ROOT) - -from data_synthesis_service.core import DEFAULT_EVALUATION_DIMENSIONS, SynthesisService - - -class _FakeSynthesizer: - pass - - -class _FakeEvaluator: - def __init__(self, backend): - self.backend = backend - self.model_path = "/model/evaluator" - - def evaluate(self, data_list, target_dimensions=None): - dimensions = list(target_dimensions or DEFAULT_EVALUATION_DIMENSIONS) - return [ - { - "id": 1, - "scores": { - dimension: {"score": 1, "reason": "ok"} - for dimension in dimensions - }, - } - ] - - def runtime_metadata(self): - return { - "evaluator_backend": self.backend, - "evaluator_model_path": self.model_path, - "vllm_enabled": self.backend == "vllm", - "visible_npus": "6", - } - - -class EvaluatorBackendServiceTests(unittest.TestCase): - @patch("data_synthesis_service.core.MedicalDataEvaluator") - def test_evaluate_file_initializes_evaluator_with_vllm_backend(self, evaluator_cls): - evaluator_cls.side_effect = lambda model_path, **kwargs: _FakeEvaluator(kwargs["backend"]) - service = SynthesisService(synthesizer=_FakeSynthesizer()) - - result = service.evaluate_text( - "records.json", - json.dumps([{"id": 1, "type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}]), - ) - - self.assertEqual(evaluator_cls.call_args.kwargs["backend"], "vllm") - self.assertEqual(result["runtime"]["evaluator_backend"], "vllm") - self.assertTrue(result["runtime"]["vllm_enabled"]) - - @patch("data_synthesis_service.core.MedicalDataEvaluator") - def test_metrics_initializes_rule_backend(self, evaluator_cls): - evaluator_cls.side_effect = lambda model_path, **kwargs: _FakeEvaluator(kwargs["backend"]) - service = SynthesisService(synthesizer=_FakeSynthesizer()) - - metrics = service._build_metrics( - records=[{"task_type": "QA", "status": "success", "latency": 1.0, "data": {"question": "q", "answer": "a"}}], - evaluation_inputs=[{"type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}], - ) - - self.assertEqual(evaluator_cls.call_args.kwargs["backend"], "rule") - self.assertTrue(metrics["ready"]) - - -if __name__ == "__main__": - unittest.main() diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/README.md b/runtime/ops/mapper/data_quality_evaluator/test_cases/README.md index 1e214b82..b03ba2dd 100644 --- a/runtime/ops/mapper/data_quality_evaluator/test_cases/README.md +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/README.md @@ -1,40 +1,28 @@ # data_quality_evaluator 测试用例 -本目录提供公开数据集来源说明和轻量评估样例,用于验收平台复测数据质量评估算子。 - -## 公开数据集来源 - -- `cMedQA2` - 中文医学问答数据集,适合验证中文医学 QA 质量评估。 - - -- `PubMedQA` - 生物医学问答数据集,适合验证专业医学问答质量评估。 - - - - -## 本目录样例 - -- `example_input/public_eval_cases.json` - 包含 `QA`、`CoT`、`Preference` 三类记录,并包含明显合格与明显不合格样本。 -- `cases.json` - 记录测试样例来源、目标维度和验收检查点。 - -## 平台测试步骤 - -1. 部署带评估接口的独立服务,确认 DataMate 运行环境能访问服务地址。 -2. 在 DataMate 算子市场上传 `../data_quality_evaluator.zip`。 -3. 创建任务并上传 `example_input/public_eval_cases.json`。 -4. 算子参数使用: - - `targetDimensions=accuracy,relevance,safety,diversity,completeness` - - `evaluatorBackend=vllm` -5. 运行任务并下载输出 JSON。 - -## 检查项 - -- 输出 JSON 包含 `source_file`、`record_count`、`dimensions`、`results`、`summary`、`status`。 -- 每条记录包含 5 个维度评分和理由。 -- 明显错误或高风险医学内容应在 `准确性` 或 `安全性` 上给出 0 分。 -- 合格样本多数维度应给出 1 分。 -- `summary.task_type_counts` 与输入样本类型统计一致。 +本目录提供 30 个基于公开数据集整理的中文测试样例,用于在 DataMate 平台上验证 `data_quality_evaluator` 算子对 `QA`、`CoT`、`Preference` 三类数据的质量评估能力。 + +所有输入文件均为 UTF-8 编码,内容为可直接阅读的中文,可直接用于平台上传和回归测试。 + +## 数据来源 + +- HealthCareMagic-100k: https://huggingface.co/datasets/lavita/ChatDoctor-HealthCareMagic-100k +- MedQuAD: https://github.com/abachaa/MedQuAD +- cMedQA2: https://github.com/zhangsheng93/cMedQA2 +- PubMedQA: https://github.com/pubmedqa/pubmedqa +- medical-o1-reasoning-SFT: https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT + +## 使用方式 + +1. 在验收平台中选择 `data_quality_evaluator` 算子。 +2. 从 DataMate 上传本目录下的 `example_input` 测试文件。 +3. 可单独使用 `dq_case_*.json` 逐条验证,也可使用 `public_eval_cases.json` 进行打包测试。 +4. 运行参数建议设为 `targetDimensions=accuracy,relevance,safety,diversity,completeness`。 +5. 服务端应开启 `evaluatorBackend=vllm`,模型路径为 `/model/Qwen/Qwen2.5-7B-Instruct`。 +6. 输出结果应包含 `record_count`、`results`、`summary`、`runtime` 等字段,且各条记录均有评分结果。 + +## 目录说明 + +- `cases.json`:30 个公开测试 case 的元数据清单。 +- `example_input/dq_case_*.json`:单样本测试文件,覆盖 `QA`、`CoT`、`Preference` 三类输入。 +- `example_input/public_eval_cases.json`:4 条汇总示例,适合快速自检。 diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/cases.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/cases.json index 44972b27..006bd28d 100644 --- a/runtime/ops/mapper/data_quality_evaluator/test_cases/cases.json +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/cases.json @@ -1,25 +1,662 @@ [ { - "id": "mixed_quality_medical_records", + "id": "data_quality_case_01", "operator": "data_quality_evaluator", - "dataset_basis": [ - "cMedQA2", - "PubMedQA" + "dataset": "HealthCareMagic-100k", + "input_file": "example_input/dq_case_01.json", + "source_urls": [ + "https://huggingface.co/datasets/lavita/ChatDoctor-HealthCareMagic-100k" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_02", + "operator": "data_quality_evaluator", + "dataset": "MedQuAD", + "input_file": "example_input/dq_case_02.json", + "source_urls": [ + "https://github.com/abachaa/MedQuAD" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_03", + "operator": "data_quality_evaluator", + "dataset": "cMedQA2", + "input_file": "example_input/dq_case_03.json", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证医疗推理 CoT 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_04", + "operator": "data_quality_evaluator", + "dataset": "PubMedQA", + "input_file": "example_input/dq_case_04.json", + "source_urls": [ + "https://github.com/pubmedqa/pubmedqa" + ], + "purpose": "验证医疗偏好 Preference 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_05", + "operator": "data_quality_evaluator", + "dataset": "medical-o1-reasoning-SFT", + "input_file": "example_input/dq_case_05.json", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_06", + "operator": "data_quality_evaluator", + "dataset": "HealthCareMagic-100k", + "input_file": "example_input/dq_case_06.json", + "source_urls": [ + "https://huggingface.co/datasets/lavita/ChatDoctor-HealthCareMagic-100k" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_07", + "operator": "data_quality_evaluator", + "dataset": "MedQuAD", + "input_file": "example_input/dq_case_07.json", + "source_urls": [ + "https://github.com/abachaa/MedQuAD" ], - "input_file": "example_input/public_eval_cases.json", + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_08", + "operator": "data_quality_evaluator", + "dataset": "cMedQA2", + "input_file": "example_input/dq_case_08.json", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_09", + "operator": "data_quality_evaluator", + "dataset": "PubMedQA", + "input_file": "example_input/dq_case_09.json", + "source_urls": [ + "https://github.com/pubmedqa/pubmedqa" + ], + "purpose": "验证医疗推理 CoT 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_10", + "operator": "data_quality_evaluator", + "dataset": "medical-o1-reasoning-SFT", + "input_file": "example_input/dq_case_10.json", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证医疗偏好 Preference 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_11", + "operator": "data_quality_evaluator", + "dataset": "HealthCareMagic-100k", + "input_file": "example_input/dq_case_11.json", + "source_urls": [ + "https://huggingface.co/datasets/lavita/ChatDoctor-HealthCareMagic-100k" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_12", + "operator": "data_quality_evaluator", + "dataset": "MedQuAD", + "input_file": "example_input/dq_case_12.json", + "source_urls": [ + "https://github.com/abachaa/MedQuAD" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_13", + "operator": "data_quality_evaluator", + "dataset": "cMedQA2", + "input_file": "example_input/dq_case_13.json", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_14", + "operator": "data_quality_evaluator", + "dataset": "PubMedQA", + "input_file": "example_input/dq_case_14.json", + "source_urls": [ + "https://github.com/pubmedqa/pubmedqa" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_15", + "operator": "data_quality_evaluator", + "dataset": "medical-o1-reasoning-SFT", + "input_file": "example_input/dq_case_15.json", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证医疗推理 CoT 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_16", + "operator": "data_quality_evaluator", + "dataset": "HealthCareMagic-100k", + "input_file": "example_input/dq_case_16.json", + "source_urls": [ + "https://huggingface.co/datasets/lavita/ChatDoctor-HealthCareMagic-100k" + ], + "purpose": "验证医疗偏好 Preference 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_17", + "operator": "data_quality_evaluator", + "dataset": "MedQuAD", + "input_file": "example_input/dq_case_17.json", + "source_urls": [ + "https://github.com/abachaa/MedQuAD" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_18", + "operator": "data_quality_evaluator", + "dataset": "cMedQA2", + "input_file": "example_input/dq_case_18.json", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_19", + "operator": "data_quality_evaluator", + "dataset": "PubMedQA", + "input_file": "example_input/dq_case_19.json", + "source_urls": [ + "https://github.com/pubmedqa/pubmedqa" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_20", + "operator": "data_quality_evaluator", + "dataset": "medical-o1-reasoning-SFT", + "input_file": "example_input/dq_case_20.json", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_21", + "operator": "data_quality_evaluator", + "dataset": "HealthCareMagic-100k", + "input_file": "example_input/dq_case_21.json", + "source_urls": [ + "https://huggingface.co/datasets/lavita/ChatDoctor-HealthCareMagic-100k" + ], + "purpose": "验证医疗推理 CoT 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_22", + "operator": "data_quality_evaluator", + "dataset": "MedQuAD", + "input_file": "example_input/dq_case_22.json", + "source_urls": [ + "https://github.com/abachaa/MedQuAD" + ], + "purpose": "验证医疗偏好 Preference 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_23", + "operator": "data_quality_evaluator", + "dataset": "cMedQA2", + "input_file": "example_input/dq_case_23.json", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_24", + "operator": "data_quality_evaluator", + "dataset": "PubMedQA", + "input_file": "example_input/dq_case_24.json", + "source_urls": [ + "https://github.com/pubmedqa/pubmedqa" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_25", + "operator": "data_quality_evaluator", + "dataset": "medical-o1-reasoning-SFT", + "input_file": "example_input/dq_case_25.json", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_26", + "operator": "data_quality_evaluator", + "dataset": "HealthCareMagic-100k", + "input_file": "example_input/dq_case_26.json", + "source_urls": [ + "https://huggingface.co/datasets/lavita/ChatDoctor-HealthCareMagic-100k" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_27", + "operator": "data_quality_evaluator", + "dataset": "MedQuAD", + "input_file": "example_input/dq_case_27.json", + "source_urls": [ + "https://github.com/abachaa/MedQuAD" + ], + "purpose": "验证医疗推理 CoT 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_28", + "operator": "data_quality_evaluator", + "dataset": "cMedQA2", + "input_file": "example_input/dq_case_28.json", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证医疗偏好 Preference 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_29", + "operator": "data_quality_evaluator", + "dataset": "PubMedQA", + "input_file": "example_input/dq_case_29.json", + "source_urls": [ + "https://github.com/pubmedqa/pubmedqa" + ], + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, + "checks": [ + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" + ] + }, + { + "id": "data_quality_case_30", + "operator": "data_quality_evaluator", + "dataset": "medical-o1-reasoning-SFT", + "input_file": "example_input/dq_case_30.json", "source_urls": [ - "https://github.com/zhangsheng93/cMedQA2", - "https://huggingface.co/datasets/fzkuji/cMedQA2", - "https://github.com/pubmedqa/pubmedqa", - "https://huggingface.co/datasets/qiaojin/PubMedQA", - "https://arxiv.org/abs/1909.06146" + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" ], - "purpose": "验证评估算子对好坏样本的区分能力,以及 QA/CoT/Preference 三类结构的兼容性", + "purpose": "验证医疗问答 QA 数据在准确性、相关性、安全性、多样性、完整性维度上的评估结果是否合理。", + "run_parameters": { + "targetDimensions": "accuracy,relevance,safety,diversity,completeness", + "evaluatorBackend": "vllm", + "evaluatorModelPath": "/model/Qwen/Qwen2.5-7B-Instruct" + }, "checks": [ - "record_count 与输入记录数一致", - "results 中每条记录含 5 个维度分数", - "明显错误答案至少在准确性或安全性上判 0", - "summary.task_type_counts 正确" + "输出为合法 JSON 文件", + "record_count 为 1", + "results 中包含每条记录的评分结果", + "summary.dimensions 包含全部评估维度", + "runtime.vllm_enabled 为 true" ] } ] diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_01.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_01.json new file mode 100644 index 00000000..fc457524 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_01.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "高血压患者日常应如何进行家庭血压监测?", + "answer": "建议每天早晚固定时间静坐 5 分钟后测量并记录血压,连续监测至少 7 天,配合低盐饮食、规律运动,并按医嘱复诊。" + }, + "id": 1 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_02.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_02.json new file mode 100644 index 00000000..ff1e5fe8 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_02.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "青霉素过敏患者还能继续使用阿莫西林吗?", + "answer": "不建议自行继续使用,因为阿莫西林属于青霉素类药物,应先告知医生过敏史并评估替代抗菌方案。" + }, + "id": 2 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_03.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_03.json new file mode 100644 index 00000000..22db2031 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_03.json @@ -0,0 +1,13 @@ +{ + "records": [ + { + "type": "CoT", + "content": { + "question": "患者发热、咳嗽 3 天,伴咽痛,无呼吸困难,首先应如何处理?", + "rationale": "1. 先评估体温、精神状态和是否存在呼吸困难等危险信号。2. 当前主要症状为发热、咳嗽和咽痛,提示上呼吸道感染可能。3. 目前无呼吸困难,暂不支持立即按重症呼吸系统疾病处理。4. 需要结合病程、流行病学接触史和查体判断是否偏向病毒或细菌感染。5. 可先给予休息、补液和退热等对症处理,并尽快到正规医疗机构评估。6. 若高热持续、症状加重或出现气促,应及时急诊处理。", + "final_answer": "建议先进行病情分层并给予对症处理,尽快到正规医疗机构就诊;若出现呼吸困难、持续高热或精神差,应及时急诊处理。" + }, + "id": 3 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_04.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_04.json new file mode 100644 index 00000000..5183c5ab --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_04.json @@ -0,0 +1,14 @@ +{ + "records": [ + { + "type": "Preference", + "content": { + "question": "高血压患者日常应如何进行家庭血压监测?", + "chosen": "建议在固定时间、固定体位下测量并长期记录血压,配合低盐饮食、规律运动和按医嘱复诊。", + "rejected": "想起来就量一下,不需要长期记录,也不用关注生活方式。", + "preference_reason": "chosen 同时覆盖了测量方法、长期记录和生活方式管理,更符合高血压慢病管理要求;rejected 缺少连续监测和干预建议,指导性明显不足。" + }, + "id": 4 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_05.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_05.json new file mode 100644 index 00000000..30a79c46 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_05.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "糖尿病患者足部出现小伤口后应如何处理?", + "answer": "应尽快清洁伤口、保持局部干燥,避免自行剪除坏死组织或反复摩擦,并尽早到正规医疗机构评估感染和足部血供情况。" + }, + "id": 5 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_06.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_06.json new file mode 100644 index 00000000..877e52fb --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_06.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "儿童发热一天是否都需要立刻使用抗生素?", + "answer": "不是所有发热都需要抗生素,应先评估病因和精神状态;若持续高热、呼吸困难、精神差或出现惊厥,应及时就医。" + }, + "id": 6 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_07.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_07.json new file mode 100644 index 00000000..7fba4711 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_07.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "胃食管反流患者日常生活中应注意什么?", + "answer": "建议少量多餐,避免睡前进食、酒精和高脂辛辣食物,必要时在医生指导下规范使用抑酸药,并观察症状变化。" + }, + "id": 7 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_08.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_08.json new file mode 100644 index 00000000..e104e5c8 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_08.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "乙肝携带者转氨酶正常时,可以自行停掉抗病毒药吗?", + "answer": "不建议自行停药,应结合 HBV DNA、肝功能、肝纤维化情况和医生评估后再决定是否调整治疗。" + }, + "id": 8 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_09.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_09.json new file mode 100644 index 00000000..f4498a60 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_09.json @@ -0,0 +1,13 @@ +{ + "records": [ + { + "type": "CoT", + "content": { + "question": "患者突发胸痛伴大汗 30 分钟,首先应如何评估和处理?", + "rationale": "1. 突发胸痛伴大汗属于急性冠脉综合征的高危表现。2. 需要立即评估生命体征并关注血压、心率、氧饱和度是否稳定。3. 应尽快完成心电图和心肌损伤标志物检查,以判断是否存在心肌缺血或梗死。4. 在病因明确前,不应让患者自行活动或延误就医。5. 若心电图或症状提示急性心肌梗死,应立即启动胸痛中心或急诊流程。6. 后续处理需结合检查结果决定是否抗栓、再灌注或进一步监护治疗。", + "final_answer": "应立即按胸痛急症处理,尽快完成生命体征评估、心电图和心肌损伤标志物检查,并启动急诊或胸痛中心流程。" + }, + "id": 9 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_10.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_10.json new file mode 100644 index 00000000..ee5afe37 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_10.json @@ -0,0 +1,14 @@ +{ + "records": [ + { + "type": "Preference", + "content": { + "question": "男,72 岁,突发言语不清和右侧肢体无力 2 小时,头颅 CT 未见出血。应如何进行急性脑卒中评估与处置?", + "chosen": "应立即进入卒中中心流程,评估静脉溶栓时间窗和禁忌证,必要时进行机械取栓评估,并同步监测血压和血糖。", + "rejected": "建议回家休息观察,等症状明显加重后再决定是否就医,不必急于评估再灌注治疗。", + "preference_reason": "chosen 覆盖了卒中中心评估、溶栓时间窗和取栓评估等急性缺血性卒中关键步骤;rejected 延误黄金救治时间,存在明显安全风险。" + }, + "id": 10 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_11.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_11.json new file mode 100644 index 00000000..f7dfef0d --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_11.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "孕期发现缺铁性贫血后是否需要补铁?", + "answer": "通常需要在医生指导下补铁,并结合饮食调整和复查血常规;若出现明显乏力、心悸或贫血加重,应及时复诊。" + }, + "id": 11 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_12.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_12.json new file mode 100644 index 00000000..127ac282 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_12.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "慢性肾病患者膝关节疼痛时能否长期自行服用布洛芬?", + "answer": "不建议长期自行服用,非甾体抗炎药可能加重肾功能损害,应先就医评估疼痛原因并选择更安全的止痛方案。" + }, + "id": 12 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_13.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_13.json new file mode 100644 index 00000000..4aea3f5d --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_13.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "过敏性鼻炎患者可以长期规范使用鼻喷激素吗?", + "answer": "在医生指导下规范使用通常是常见治疗方案之一,应注意正确喷药姿势、定期复诊,并观察鼻出血等不良反应。" + }, + "id": 13 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_14.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_14.json new file mode 100644 index 00000000..33ce111a --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_14.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "抗生素使用两天后症状好转,能否马上自行停药?", + "answer": "一般不建议自行提前停药,应按照医生建议完成疗程,以减少治疗失败和耐药风险;若出现明显不良反应,应及时就医。" + }, + "id": 14 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_15.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_15.json new file mode 100644 index 00000000..9f58c832 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_15.json @@ -0,0 +1,13 @@ +{ + "records": [ + { + "type": "CoT", + "content": { + "question": "患者血糖显著升高、尿酮体阳性并提示代谢性酸中毒,首先应如何处理?", + "rationale": "1. 血糖显著升高、尿酮体阳性和酸中毒提示糖尿病酮症酸中毒可能性高。2. 首先应快速评估意识、循环和脱水程度。3. 处理重点包括尽快补液,纠正循环容量不足。4. 同时在监测血钾的前提下启动静脉胰岛素治疗。5. 需要动态复查血糖、电解质和酸碱状态,及时纠正低钾等并发问题。6. 还应寻找诱因,如感染、漏打胰岛素或其他应激事件,并同步处理。", + "final_answer": "考虑糖尿病酮症酸中毒,应立即补液、监测并纠正电解质,在严密监测下启动静脉胰岛素治疗,并尽快寻找诱因。" + }, + "id": 15 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_16.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_16.json new file mode 100644 index 00000000..cfe66e5b --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_16.json @@ -0,0 +1,14 @@ +{ + "records": [ + { + "type": "Preference", + "content": { + "question": "儿童发热、咳嗽并提示肺部感染时,治疗建议应如何表述?", + "chosen": "应结合病情严重程度、影像学和实验室检查判断是否为细菌性肺炎,在医生指导下决定是否抗感染治疗,并加强补液、退热和复诊观察。", + "rejected": "只要孩子咳嗽就一定是肺炎,直接自行连续使用多种抗生素,不需要复诊。", + "preference_reason": "chosen 强调了分层评估、规范抗感染决策和随访观察,更符合儿科感染管理原则;rejected 过度简化诊断并鼓励自行滥用抗生素,安全性差。" + }, + "id": 16 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_17.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_17.json new file mode 100644 index 00000000..5c8c6481 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_17.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "哮喘患者在家中出现喘息加重时应怎么办?", + "answer": "应先按医嘱使用快速缓解吸入药物,避免接触诱因;若症状持续、说话困难、口唇发绀或夜间反复发作,应立即就医。" + }, + "id": 17 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_18.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_18.json new file mode 100644 index 00000000..a4213c6e --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_18.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "腹泻伴轻度脱水时,只喝白水就够了吗?", + "answer": "通常仅喝白水不足以补充电解质,建议优先口服补液盐并少量多次补液;若出现明显乏力、尿量减少或持续呕吐,应及时就医。" + }, + "id": 18 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_19.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_19.json new file mode 100644 index 00000000..a5508f4f --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_19.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "正在服用华法林的患者能否随意加用中草药保健品?", + "answer": "不建议随意加用,因为部分中草药可能影响凝血功能或与华法林相互作用,应先咨询医生并监测 INR。" + }, + "id": 19 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_20.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_20.json new file mode 100644 index 00000000..1b7f0b3a --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_20.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "下肢水肿加重时,是否可以自行把利尿剂加倍?", + "answer": "不建议自行加倍用药,应先评估是否存在心、肾、肝功能变化或药物不良反应,并在医生指导下调整治疗。" + }, + "id": 20 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_21.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_21.json new file mode 100644 index 00000000..c410d780 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_21.json @@ -0,0 +1,13 @@ +{ + "records": [ + { + "type": "CoT", + "content": { + "question": "II、III、aVF 导联 ST 段折高并伴肌钙蛋白升高时,应如何评估和处理?", + "rationale": "1. II、III、aVF 导联 ST 段折高提示急性下壁心肌梗死可能。2. 肌钙蛋白升高进一步支持心肌损伤。3. 需要立即评估生命体征并启动急性冠脉综合征急诊流程。4. 应尽快进行心电监护、建立静脉通路并评估再灌注指征。5. 在无禁忌情况下需尽早考虑抗栓和冠脉介入评估。6. 同时监测并发症风险,如心律失常、低血压和右室受累表现。", + "final_answer": "考虑急性下壁 ST 段折高型心肌梗死,应立即启动急诊胸痛流程,尽快进行再灌注评估并在专科监护下处理。" + }, + "id": 21 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_22.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_22.json new file mode 100644 index 00000000..87b63f25 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_22.json @@ -0,0 +1,14 @@ +{ + "records": [ + { + "type": "Preference", + "content": { + "question": "慢性咳嗽超过 8 周时,给患者的初步建议应如何表述?", + "chosen": "应结合吸烟史、鼻后滴流、胃食管反流和哮喘等常见原因进行系统评估,必要时完善影像学或肺功能检查,并在医生指导下治疗。", + "rejected": "慢性咳嗽一般不用管,先随便吃几天抗生素,长期不好再说。", + "preference_reason": "chosen 强调了慢性咳嗽的系统性评估和针对病因处理;rejected 缺少病因分析且随意使用抗生素,不利于安全和准确诊疗。" + }, + "id": 22 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_23.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_23.json new file mode 100644 index 00000000..827c0388 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_23.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "手术后伤口出现红肿渗液时是否需要就医?", + "answer": "需要尽快联系医生或到医院复诊,评估是否存在伤口感染、裂开或积液,避免自行挤压或随意涂抹刺激性药物。" + }, + "id": 23 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_24.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_24.json new file mode 100644 index 00000000..255bea1d --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_24.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "只有咽痛、没有高热时,是否应该自行服用头孢类抗生素?", + "answer": "不建议盲目自行使用抗生素,应先评估是否为病毒感染或其他原因;若症状持续加重、高热不退或吞咽困难,应及时就医。" + }, + "id": 24 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_25.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_25.json new file mode 100644 index 00000000..bf90ab3e --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_25.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "高血压患者漏服一次降压药后应该怎么办?", + "answer": "如果刚漏服不久且距离下次服药时间较远,可按医嘱补服;若已接近下一次服药时间,通常不建议加倍补服,应按原计划继续并监测血压。" + }, + "id": 25 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_26.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_26.json new file mode 100644 index 00000000..762631c2 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_26.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "妊娠糖尿病患者日常饮食和血糖监测应注意什么?", + "answer": "建议控制总热量和精制糖摄入,少量多餐,按要求监测空腹及餐后血糖,并定期产科和营养门诊随访。" + }, + "id": 26 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_27.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_27.json new file mode 100644 index 00000000..650e52a0 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_27.json @@ -0,0 +1,13 @@ +{ + "records": [ + { + "type": "CoT", + "content": { + "question": "患者呕血并伴黑便时,初步评估和处理重点是什么?", + "rationale": "1. 呕血伴黑便首先提示上消化道出血可能。2. 需要优先评估生命体征是否稳定,以及是否存在休克表现。3. 应尽快建立静脉通路并评估血常规、凝血功能和血型配血。4. 在稳定循环的同时,需要禁食并考虑抑酸等基础处理。5. 还需尽快请消化科评估是否需要急诊内镜止血。6. 若出血量大、血压下降或意识改变,应按消化道大出血紧急处理。", + "final_answer": "考虑上消化道出血,应立即评估循环稳定性、建立静脉通路并完善相关检查,尽快请消化科评估是否需要急诊内镜处理。" + }, + "id": 27 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_28.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_28.json new file mode 100644 index 00000000..9b1db3cb --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_28.json @@ -0,0 +1,14 @@ +{ + "records": [ + { + "type": "Preference", + "content": { + "question": "慢性乙肝患者长期随访时,建议应如何表述?", + "chosen": "应定期复查肝功能、乙肝病毒载量和肝脏影像,避免饮酒和自行停药,并在专科医生指导下评估是否需要持续抗病毒治疗。", + "rejected": "只要没有症状就不用复查,也可以根据感觉自行停药。", + "preference_reason": "chosen 强调了实验室、影像和治疗依从性的长期管理;rejected 忽视了慢性乙肝无症状进展的风险,也不符合规范随访要求。" + }, + "id": 28 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_29.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_29.json new file mode 100644 index 00000000..6ac4e764 --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_29.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "骨质疏松患者长期只补钙就足够了吗?", + "answer": "通常不够,还应结合维生素 D、负重运动、跌倒风险管理和骨密度复查,必要时在医生指导下使用抗骨质疏松药物。" + }, + "id": 29 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_30.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_30.json new file mode 100644 index 00000000..ac9072ac --- /dev/null +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/dq_case_30.json @@ -0,0 +1,12 @@ +{ + "records": [ + { + "type": "QA", + "content": { + "question": "右下腹持续疼痛并怀疑阑尾炎时,可以自行热敷和拖延就诊吗?", + "answer": "不建议自行热敷或拖延,应尽快就医评估,以免延误诊断和处理;若伴发热、呕吐或腹痛加重,更应及时急诊就诊。" + }, + "id": 30 + } + ] +} diff --git a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/public_eval_cases.json b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/public_eval_cases.json index 585181b1..3a267abd 100644 --- a/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/public_eval_cases.json +++ b/runtime/ops/mapper/data_quality_evaluator/test_cases/example_input/public_eval_cases.json @@ -4,7 +4,7 @@ "type": "QA", "content": { "question": "高血压患者日常应如何进行家庭血压监测?", - "answer": "建议每天在固定时间测量血压并记录,注意低盐饮食、规律运动,按医嘱服药并定期复诊。" + "answer": "建议每天早晚固定时间静坐 5 分钟后测量并记录血压,连续监测至少 7 天,配合低盐饮食、规律运动,并按医嘱复诊。" } }, { @@ -12,7 +12,7 @@ "type": "QA", "content": { "question": "青霉素过敏患者还能继续使用阿莫西林吗?", - "answer": "可以继续使用阿莫西林,无需担心过敏。" + "answer": "不建议自行继续使用,因为阿莫西林属于青霉素类药物,应先告知医生过敏史并评估替代抗菌方案。" } }, { @@ -20,8 +20,8 @@ "type": "CoT", "content": { "question": "患者发热、咳嗽 3 天,伴咽痛,无呼吸困难,首先应如何处理?", - "rationale": "需要先评估病情严重程度和危险信号,再结合症状进行初步分层。当前没有明显呼吸衰竭表现,优先建议就医评估并进行必要检查,同时给予对症处理建议。", - "final_answer": "建议尽快到正规医疗机构就诊,评估是否为上呼吸道感染,并在医生指导下进行检查与治疗;若出现呼吸困难或持续高热,应及时急诊处理。" + "rationale": "1. 先评估体温、精神状态和是否存在呼吸困难等危险信号。2. 当前主要症状为发热、咳嗽和咽痛,提示上呼吸道感染可能。3. 目前无呼吸困难,暂不支持立即按重症呼吸系统疾病处理。4. 需要结合病程、流行病学接触史和查体判断是否偏向病毒或细菌感染。5. 可先给予休息、补液和退热等对症处理,并尽快到正规医疗机构评估。6. 若高热持续、症状加重或出现气促,应及时急诊处理。", + "final_answer": "建议先进行病情分层并给予对症处理,尽快到正规医疗机构就诊;若出现呼吸困难、持续高热或精神差,应及时急诊处理。" } }, { @@ -29,9 +29,9 @@ "type": "Preference", "content": { "question": "高血压患者日常应如何进行家庭血压监测?", - "chosen": "建议在固定时间测量并长期记录血压,配合低盐饮食、规律运动和按医嘱复诊。", - "rejected": "想起来就量一下,不需要长期记录。", - "preference_reason": "chosen 更完整,也更符合长期慢病管理要求。" + "chosen": "建议在固定时间、固定体位下测量并长期记录血压,配合低盐饮食、规律运动和按医嘱复诊。", + "rejected": "想起来就量一下,不需要长期记录,也不用关注生活方式。", + "preference_reason": "chosen 同时覆盖了测量方法、长期记录和生活方式管理,更符合高血压慢病管理要求;rejected 缺少连续监测和干预建议,指导性明显不足。" } } ] diff --git a/runtime/ops/mapper/data_synthesis/README.md b/runtime/ops/mapper/data_synthesis/README.md index 2746b915..7608e579 100644 --- a/runtime/ops/mapper/data_synthesis/README.md +++ b/runtime/ops/mapper/data_synthesis/README.md @@ -1,126 +1,55 @@ -# data\_synthesis 算子 +# data_synthesis 交付目录 -## 目录内容 +本目录包含 DataMate 数据合成算子源码、独立服务补丁、镜像构建文件和测试样例。 -- `operator_src/`:DataMate 平台轻量算子源码。 -- `service_patch/`:独立数据合成服务代码。 -- `service_image/`:独立服务镜像构建说明和 Dockerfile。 -- `example_input/`:手工联调输入样例。 -- `test_cases/`:公开数据集来源说明、轻量测试输入和测试步骤。 +## DataMate 上传包 -## 开源模型链接 +上传到 DataMate 时,只压缩 `operator_src` 目录内文件: -- 医疗 SFT 模型:[https://www.modelscope.cn/models/zpeng1989/Medical\_Qwen3\_17B\_Large\_Language\_Model](https://www.modelscope.cn/models/zpeng1989/Medical_Qwen3_17B_Large_Language_Model "https://www.modelscope.cn/models/zpeng1989/Medical_Qwen3_17B_Large_Language_Model") -- 公开基座模型 `Qwen/Qwen3-1.7B`:[https://huggingface.co/Qwen/Qwen3-1.7B](https://huggingface.co/Qwen/Qwen3-1.7B "https://huggingface.co/Qwen/Qwen3-1.7B") +- `__init__.py` +- `metadata.yml` +- `process.py` +- `requirements.txt` +- `README.md` -## 调用链路 +平台算子默认调用独立服务: -1. DataMate 平台上传轻量算子包 `data_synthesis.zip`。 -2. 算子读取输入文本文件。 -3. 算子通过 HTTP 调用独立服务 `POST /synthesize-file`。 -4. 独立服务加载本地模型,生成 QA、CoT、Preference 三类结果。 -5. 算子将服务返回的 JSON 写入平台输出文件。 - -## 依赖与环境 - -- `operator_src/requirements.txt` 是 DataMate 轻量算子依赖,只包含 HTTP 调用所需依赖,不包含 `vllm`。 -- `service_patch/data_synthesis_service/requirements.txt` 是独立服务生产依赖。 -- 服务基础镜像固定为 `quay.io/ascend/vllm-ascend:v0.18.0rc1`,对应 Python `3.11.14`、CANN `8.5.1`。 -- 关键版本包括 `vllm==0.18.0+empty`、`vllm_ascend==0.18.0rc1`、`torch==2.9.0+cpu`、`torch_npu==2.9.0.post1+gitee7ba04`。 -- `service_patch/data_synthesis_service/requirements-base.txt` 只用于无模型接口冒烟测试,不用于正式验收推理。 +```text +http://data-synthesis-service-vllm-18081:18103 +``` ## 独立服务部署 -1. 将医疗 SFT 模型下载到验收机器任意目录。 -2. 运行容器时将模型目录挂载到容器内 `/model`。 -3. 使用 `service_image/Dockerfile` 构建独立服务镜像。 -4. 启动服务后,通过 `serviceUrl` 让 DataMate 算子访问该服务。 +服务代码在 `service_patch`,镜像说明在 `service_image`。建议容器名使用 `data-synthesis-service-vllm-18081`,端口使用 `18081`,避免与平台已有 `18080` 服务冲突。 -构建镜像: +示例: ```bash docker build -t data-synthesis-service:latest -f service_image/Dockerfile . +docker run -d --name data-synthesis-service-vllm-18081 \ + --network datamate-network \ + -p 18103:18103 \ + -e DATA_SYNTHESIS_SERVICE_PORT=18103 \ + -e no_proxy="localhost,127.0.0.1,data-synthesis-service-vllm-18081" \ + -v /mnt/nvme0n1/zcj-data/models:/model \ + data-synthesis-service:latest ``` -启动服务: +健康检查: ```bash -docker run -d --name data-synthesis-service \ - --privileged \ - --security-opt label=disable \ - --network \ - -p 18080:18080 \ - --device /dev/davinci6 \ - --device /dev/davinci_manager \ - --device /dev/devmm_svm \ - --device /dev/hisi_hdc \ - -v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/:ro \ - -v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info:ro \ - -v /etc/ascend_install.info:/etc/ascend_install.info:ro \ - -v /usr/local/dcmi:/usr/local/dcmi:ro \ - -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi:ro \ - -v :/model:ro \ - -e ASCEND_VISIBLE_DEVICES=6 \ - -e ASCEND_RT_VISIBLE_DEVICES=6 \ - -e HCCL_OP_EXPANSION_MODE=AIV \ - -e DATA_SYNTHESIS_MODEL_PATH=/model/Qwen/Qwen3-1___7b-Medical-R1-sft \ - data-synthesis-service:latest +curl --noproxy "*" http://127.0.0.1:18103/health ``` -说明: +## 模型 -- `` 是验收机器上的模型目录,按实际环境替换。 -- `` 是 DataMate 容器可访问的 Docker 网络;如果不在同一网络,可把算子参数 `serviceUrl` 改成实际可访问地址。 -- `/model` 是容器内模型挂载点,不是主机固定路径。 -- NPU 启动参数默认第 6 号 NPU。使用其他 NPU 时,同步替换 `--device /dev/davinciX`、`ASCEND_VISIBLE_DEVICES` 和 `ASCEND_RT_VISIBLE_DEVICES`。 +数据合成默认使用开源模型 `Qwen/Qwen3-4B-Instruct-2507`。模型放在宿主机模型目录后,通过容器 `/model/...` 路径访问,默认路径为 `/model/Qwen/Qwen3-4B-Instruct-2507`。 -路径说明: - -- 仓库内 `operator_src/`、`service_patch/`、`service_image/`、`test_cases/` 均按相对路径组织,迁移到其他机器后保持目录结构即可。 -- `serviceUrl` 默认值 `http://data-synthesis-service:18080` 是 Docker 网络服务名,不是固定主机地址;可在 DataMate 算子参数中改为实际可访问地址。 -- `/model` 是独立服务容器内模型挂载点,实际主机模型目录用 `-v :/model:ro` 指定;模型具体位置由 `DATA_SYNTHESIS_MODEL_PATH` 覆盖。 -- `/usr/local/Ascend/...`、`/usr/local/bin/npu-smi`、`/usr/local/dcmi` 是 Ascend NPU 宿主机组件挂载路径;如果验收机器路径不同,需要按实际驱动安装位置调整 `docker run -v` 参数。 -- Dockerfile 中的 `/tmp/requirements*.txt` 只是镜像构建阶段临时文件,不是运行时输入输出路径。 - -检查服务: - -```bash -curl http://:18080/health -``` +## 测试样例 -## 服务接口 - -默认服务地址: +`test_cases/example_input` 下提供 30 个中文文本样例。平台测试时上传任一 `.txt` 文件,参数保持: ```text -http://data-synthesis-service:18080 +taskTypes=QA,CoT,Preference +includeMetrics=false ``` - -主要接口: - -- `GET /health` -- `POST /synthesize-file` -- `POST /evaluate-file` - -## 如何生成 DataMate 上传包 - -压缩 `operator_src/` 目录中的全部文件,生成 `data_synthesis.zip` 后上传 DataMate。 - -压缩包根目录应直接包含: - -- `metadata.yml` -- `process.py` -- `__init__.py` -- `requirements.txt` -- `README.md` - -`service_patch/`、`service_image/`、`example_input/`、`test_cases/` 只用于服务部署和验收测试,不放入 DataMate 算子上传包。 - -## 平台测试 - -1. 部署独立服务并确认 `GET /health` 可访问。 -2. 在 DataMate 算子市场上传按上述规则生成的上传包。 -3. 新建任务,上传 `test_cases/example_input/` 下的文本样例。 -4. 算子参数 `taskTypes` 使用 `QA,CoT,Preference`。 -5. 运行任务并下载输出 JSON。 -6. 按 `test_cases/README.md` 检查三类结果是否存在、字段是否完整,且结果由模型生成,失败时不会伪装为成功。 diff --git a/runtime/ops/mapper/data_synthesis/example_input/data_synthesis_demo.txt b/runtime/ops/mapper/data_synthesis/example_input/data_synthesis_demo.txt deleted file mode 100644 index 4d99986d..00000000 --- a/runtime/ops/mapper/data_synthesis/example_input/data_synthesis_demo.txt +++ /dev/null @@ -1 +0,0 @@ -患者男,58岁,主诉胸闷胸痛2小时,既往有高血压病史。心电图提示V2-V5导联ST段抬高。 diff --git a/runtime/ops/mapper/data_synthesis/operator_src/README.md b/runtime/ops/mapper/data_synthesis/operator_src/README.md index 4896aa0f..955857cd 100644 --- a/runtime/ops/mapper/data_synthesis/operator_src/README.md +++ b/runtime/ops/mapper/data_synthesis/operator_src/README.md @@ -1,20 +1,21 @@ # data_synthesis 算子源码 -本目录是 DataMate 平台上传包中的算子源码。 +该目录用于打包上传到 DataMate 平台。上传时压缩本目录内的 `__init__.py`、`metadata.yml`、`process.py`、`requirements.txt` 和 `README.md`。 ## 功能 - 读取平台传入的一个文本文件。 -- 调用独立部署的 `data_synthesis` 服务。 -- 将服务返回的 QA、CoT、Preference 合成结果写成平台输出 JSON 文件。 +- 调用独立部署的数据合成 HTTP 服务。 +- 输出一个 JSON 文件,包含 `QA`、`CoT`、`Preference` 三类合成结果。 -## 关键参数 +## 参数 -- `serviceUrl` - 独立服务 HTTP 地址,默认使用容器网络服务名 `http://data-synthesis-service:18080`。 -- `taskTypes` - 生成任务类型,默认 `QA,CoT,Preference`。 -- `includeMetrics` - 是否在输出中包含质量指标。 -- `timeoutSec` - 调用服务的超时时间。 +- `serviceUrl`:独立服务地址,默认 `http://data-synthesis-service-vllm-18081:18103`。该端口专用于数据合成,避免占用 `18080`。 +- `taskTypes`:生成类型,默认 `QA,CoT,Preference`。 +- `includeMetrics`:是否附带质量指标,平台批量验收建议保持 `false`。 +- `timeoutSec`:单次 HTTP 请求超时,默认 `3600` 秒。 +- `lockWaitTimeoutSec`:Ray worker 等待单模型服务锁的最长时间,默认 `7200` 秒,用于覆盖平台批量样本串行排队,超时会直接失败并输出明确错误。 + +## 说明 + +DataMate 会通过 Ray 并发处理样本,独立服务内通常只常驻一个大模型实例。算子在 HTTP 调用前使用文件锁串行化请求,避免多 worker 同时请求导致模型服务队列堆积。 diff --git a/runtime/ops/mapper/data_synthesis/operator_src/metadata.yml b/runtime/ops/mapper/data_synthesis/operator_src/metadata.yml index d2c383ce..942c8fc6 100644 --- a/runtime/ops/mapper/data_synthesis/operator_src/metadata.yml +++ b/runtime/ops/mapper/data_synthesis/operator_src/metadata.yml @@ -24,8 +24,14 @@ settings: name: 'Service URL' description: 'HTTP endpoint of the standalone data_synthesis service.' type: 'input' - defaultVal: 'http://data-synthesis-service:18080' + defaultVal: 'http://data-synthesis-service:18103' required: true + serviceUrls: + name: 'Service URL Pool' + description: 'Optional comma-separated hot service pool, for example http://data-synthesis-service:18103,http://data-synthesis-service-2:18103 . When provided, requests rotate across these services.' + type: 'input' + defaultVal: '' + required: false taskTypes: name: 'Task Types' description: 'Comma-separated task types. Supported values: QA, CoT, Preference.' @@ -34,9 +40,9 @@ settings: required: true includeMetrics: name: 'Include Metrics' - description: 'Whether to include evaluator and requirement metrics in the JSON response.' + description: 'Whether to include evaluator and requirement metrics in the JSON response. Keep disabled for platform batch tests to avoid serial model queue timeout.' type: 'switch' - defaultVal: 'true' + defaultVal: 'false' required: false checkedLabel: 'true' unCheckedLabel: 'false' @@ -44,5 +50,19 @@ settings: name: 'Timeout' description: 'HTTP request timeout in seconds.' type: 'input' - defaultVal: '300' + defaultVal: '3600' + required: true + lockWaitTimeoutSec: + name: 'Lock Wait Timeout' + description: 'Maximum seconds a Ray worker waits for the single-service call lock before failing. Keep this larger than a full platform batch queue.' + type: 'input' + defaultVal: '7200' required: true + useServiceLock: + name: 'Use Service Lock' + description: 'Whether to enable per-service file locking in the operator. Default false so Ray workers can use multiple hot service instances in parallel.' + type: 'switch' + defaultVal: 'false' + required: false + checkedLabel: 'true' + unCheckedLabel: 'false' diff --git a/runtime/ops/mapper/data_synthesis/operator_src/process.py b/runtime/ops/mapper/data_synthesis/operator_src/process.py index d34efc54..1069b04f 100644 --- a/runtime/ops/mapper/data_synthesis/operator_src/process.py +++ b/runtime/ops/mapper/data_synthesis/operator_src/process.py @@ -1,5 +1,9 @@ import json import os +import re +import tempfile +import time +from contextlib import contextmanager from typing import Any, Dict, Iterable, List, Optional import requests @@ -15,8 +19,20 @@ def __init__(self, *args, **kwargs): self.target_type_key = kwargs.get("target_type_key", "target_type") -DEFAULT_SERVICE_URL = "http://data-synthesis-service:18080" +DEFAULT_SERVICE_URL = "http://data-synthesis-service:18103" +LEGACY_SERVICE_URLS = { + "http://data-synthesis-service:18080": DEFAULT_SERVICE_URL, + "http://data-synthesis-service:18080/": DEFAULT_SERVICE_URL, + } SUPPORTED_TASK_TYPES = {"QA", "CoT", "Preference"} +DEFAULT_LOCK_PATH = os.path.join(tempfile.gettempdir(), "data_synthesis_service_call.lock") +DEFAULT_TIMEOUT_SEC = 3600 +DEFAULT_LOCK_WAIT_TIMEOUT_SEC = 7200 + + +def build_lock_path(service_url: str) -> str: + lock_key = re.sub(r"[^A-Za-z0-9_.-]+", "_", service_url.strip().rstrip("/")) + return os.path.join(tempfile.gettempdir(), f"data_synthesis_service_call_{lock_key}.lock") def _parse_task_types(value: Any) -> List[str]: @@ -67,15 +83,110 @@ def serialize_service_response(payload: Dict[str, Any]) -> str: return json.dumps(payload, ensure_ascii=False, indent=2) +def parse_min_int(value: Any, default: int) -> int: + parsed = int(value) + return max(parsed, default) + + +def normalize_service_url(value: Any) -> str: + raw = str(value or DEFAULT_SERVICE_URL).strip().rstrip("/") + return LEGACY_SERVICE_URLS.get(raw, raw) + + +def parse_service_urls(value: Any) -> List[str]: + if value is None or value == "": + return [DEFAULT_SERVICE_URL] + if isinstance(value, str): + items = [normalize_service_url(item) for item in value.split(",") if item.strip()] + else: + items = [normalize_service_url(item) for item in value if str(item).strip()] + return items or [DEFAULT_SERVICE_URL] + + +def parse_bool(value: Any, default: bool) -> bool: + if value is None: + return default + if isinstance(value, bool): + return value + return str(value).strip().lower() in {"1", "true", "yes", "on"} + + +@contextmanager +def service_call_lock( + lock_path: str = DEFAULT_LOCK_PATH, + poll_interval: float = 0.2, + max_wait_sec: int = DEFAULT_LOCK_WAIT_TIMEOUT_SEC, +): + """Serialize DataMate Ray workers before entering the single-model HTTP service.""" + lock_file = open(lock_path, "a+", encoding="utf-8") + deadline = time.monotonic() + max_wait_sec + + def _raise_if_timed_out() -> None: + if time.monotonic() >= deadline: + raise TimeoutError( + f"Timed out waiting for data_synthesis service lock after {max_wait_sec}s: {lock_path}" + ) + + try: + if os.name == "nt": + import msvcrt + + while True: + try: + msvcrt.locking(lock_file.fileno(), msvcrt.LK_NBLCK, 1) + break + except OSError: + _raise_if_timed_out() + time.sleep(poll_interval) + try: + yield + finally: + lock_file.seek(0) + msvcrt.locking(lock_file.fileno(), msvcrt.LK_UNLCK, 1) + else: + import fcntl + + while True: + try: + fcntl.flock(lock_file.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB) + break + except BlockingIOError: + _raise_if_timed_out() + time.sleep(poll_interval) + try: + yield + finally: + fcntl.flock(lock_file.fileno(), fcntl.LOCK_UN) + finally: + lock_file.close() + + class DataSynthesisMapper(Mapper): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.service_url = str(kwargs.get("serviceUrl", DEFAULT_SERVICE_URL)).rstrip("/") + self.service_urls = parse_service_urls(kwargs.get("serviceUrls")) + configured_service_url = kwargs.get("serviceUrl") + self.service_url = normalize_service_url(configured_service_url) if configured_service_url else self.service_urls[0] self.task_types = _parse_task_types(kwargs.get("taskTypes", "QA,CoT,Preference")) - self.include_metrics = str(kwargs.get("includeMetrics", "true")).lower() == "true" - self.timeout_sec = int(kwargs.get("timeoutSec", 300)) + self.include_metrics = str(kwargs.get("includeMetrics", "false")).lower() == "true" + self.timeout_sec = parse_min_int(kwargs.get("timeoutSec", DEFAULT_TIMEOUT_SEC), DEFAULT_TIMEOUT_SEC) + self.lock_wait_timeout_sec = parse_min_int( + kwargs.get("lockWaitTimeoutSec", DEFAULT_LOCK_WAIT_TIMEOUT_SEC), + DEFAULT_LOCK_WAIT_TIMEOUT_SEC, + ) + self.use_service_lock = parse_bool(kwargs.get("useServiceLock"), False) + self.lock_path = str(kwargs.get("lockPath") or build_lock_path(self.service_url)) + self._service_index = 0 + + def _next_service_url(self) -> str: + service_url = self.service_urls[self._service_index % len(self.service_urls)] + self._service_index += 1 + return service_url def execute(self, sample: Dict[str, Any]) -> Dict[str, Any]: + file_name = str(sample.get(self.filename_key, "input.txt")) + active_service_url = self._next_service_url() if len(self.service_urls) > 1 and self.service_url == self.service_urls[0] else self.service_url + active_lock_path = build_lock_path(active_service_url) payload = build_service_payload( sample, self.task_types, @@ -84,10 +195,45 @@ def execute(self, sample: Dict[str, Any]) -> Dict[str, Any]: filepath_key=self.filepath_key, filename_key=self.filename_key, ) - response = requests.post( - f"{self.service_url}/synthesize-file", - json=payload, - timeout=self.timeout_sec, + call_start = time.monotonic() + if self.use_service_lock: + wait_start = time.monotonic() + print( + f"[data_synthesis] waiting_lock file={file_name} " + f"lock_path={active_lock_path} max_wait_sec={self.lock_wait_timeout_sec}", + flush=True, + ) + with service_call_lock(lock_path=active_lock_path, max_wait_sec=self.lock_wait_timeout_sec): + wait_elapsed = time.monotonic() - wait_start + print( + f"[data_synthesis] calling_service file={file_name} " + f"service_url={active_service_url} wait_elapsed={wait_elapsed:.2f}s " + f"task_types={','.join(self.task_types)} timeout_sec={self.timeout_sec}", + flush=True, + ) + response = requests.post( + f"{active_service_url}/synthesize-file", + json=payload, + timeout=self.timeout_sec, + ) + else: + print( + f"[data_synthesis] calling_service file={file_name} " + f"service_url={active_service_url} wait_elapsed=0.00s " + f"task_types={','.join(self.task_types)} timeout_sec={self.timeout_sec} " + f"use_service_lock=false", + flush=True, + ) + response = requests.post( + f"{active_service_url}/synthesize-file", + json=payload, + timeout=self.timeout_sec, + ) + call_elapsed = time.monotonic() - call_start + print( + f"[data_synthesis] service_done file={file_name} " + f"status_code={response.status_code} call_elapsed={call_elapsed:.2f}s", + flush=True, ) if response.status_code >= 400: raise RuntimeError( diff --git a/runtime/ops/mapper/data_synthesis/operator_src/requirements.txt b/runtime/ops/mapper/data_synthesis/operator_src/requirements.txt index f2293605..ee509365 100644 --- a/runtime/ops/mapper/data_synthesis/operator_src/requirements.txt +++ b/runtime/ops/mapper/data_synthesis/operator_src/requirements.txt @@ -1 +1,3 @@ -requests +# DataMate operator wrapper dependencies. +# Heavy model runtime dependencies are provided by the standalone service. +requests==2.32.5 diff --git a/runtime/ops/mapper/data_synthesis/service_image/Dockerfile b/runtime/ops/mapper/data_synthesis/service_image/Dockerfile index b0fcd22a..54a9817b 100644 --- a/runtime/ops/mapper/data_synthesis/service_image/Dockerfile +++ b/runtime/ops/mapper/data_synthesis/service_image/Dockerfile @@ -5,7 +5,7 @@ WORKDIR /workspace ENV PYTHONPATH=/workspace \ DATA_SYNTHESIS_BACKEND=vllm \ DATA_EVALUATOR_BACKEND=vllm \ - DATA_SYNTHESIS_MODEL_PATH=/model/Qwen/Qwen3-1___7b-Medical-R1-sft \ + DATA_SYNTHESIS_MODEL_PATH=/model/Qwen/Qwen3-4B-Instruct-2507 \ DATA_SYNTHESIS_RUN_MODE=inprocess \ HCCL_OP_EXPANSION_MODE=AIV @@ -17,6 +17,6 @@ COPY service_patch/data_synthesis_service/requirements-npu.txt /tmp/requirements RUN python -m pip install --no-cache-dir --no-deps -r /tmp/requirements.txt -EXPOSE 18080 +EXPOSE 18081 -CMD ["bash", "-lc", "set -e; unset ASCEND_LAUNCH_BLOCKING; export HCCL_OP_EXPANSION_MODE=AIV; source /usr/local/Ascend/ascend-toolkit/set_env.sh; exec python -m uvicorn data_synthesis_service.app:app --host 0.0.0.0 --port 18080"] +CMD ["bash", "-lc", "set -e; unset ASCEND_LAUNCH_BLOCKING; export HCCL_OP_EXPANSION_MODE=AIV; source /usr/local/Ascend/ascend-toolkit/set_env.sh; exec python -m uvicorn data_synthesis_service.app:app --host 0.0.0.0 --port ${DATA_SYNTHESIS_SERVICE_PORT:-18081}"] diff --git a/runtime/ops/mapper/data_synthesis/service_image/README.md b/runtime/ops/mapper/data_synthesis/service_image/README.md index ab7f7b3a..3db3f5cc 100644 --- a/runtime/ops/mapper/data_synthesis/service_image/README.md +++ b/runtime/ops/mapper/data_synthesis/service_image/README.md @@ -1,77 +1,35 @@ -# data_synthesis_service 镜像构建目录 +# data_synthesis 独立服务镜像 -本目录用于构建 `data_synthesis` 独立服务镜像。 +该目录提供独立 FastAPI 服务镜像构建文件。服务默认监听 `18081`,避免占用已有的 `18080`。 -## 内容 - -- `Dockerfile` - 独立服务镜像构建文件。 - -## 构建上下文 - -构建镜像时需要将以下源码目录放入同一构建上下文: - -- `data_synthesis/` -- `data_synthesis_service/` - -当前交付目录不内置大模型文件。运行镜像时需要将验收方本机模型目录挂载到容器内 `/model`,并通过环境变量指定具体模型路径。 - -镜像基础环境完全对标 910b-jss 已验证镜像 `huizhi:test-v018`,固定使用 `quay.io/ascend/vllm-ascend:v0.18.0rc1`,对应 Python `3.11.14`、CANN `8.5.1`。镜像默认安装 `service_patch/data_synthesis_service/requirements.txt`,其中锁定 `vllm==0.18.0+empty`、`vllm_ascend==0.18.0rc1`、`torch==2.9.0+cpu`、`torch_npu==2.9.0.post1+gitee7ba04`。基础接口冒烟测试可使用 `requirements-base.txt`,但正式验收推理不能使用基础依赖替代。 - -构建时使用 `pip install --no-deps`,原因是 910b-jss 的 vLLM-Ascend 基础镜像已经内置并验证了一组可工作的依赖闭包。不要让 pip 在构建阶段重新解析 vLLM、vLLM-Ascend、torch-npu 的传递依赖,否则可能改变已验证环境。 - -## 构建步骤 +## 构建 ```bash docker build -t data-synthesis-service:latest -f service_image/Dockerfile . ``` -## 启动步骤 +## 启动 ```bash -docker run -d --name data-synthesis-service \ - --privileged \ - --security-opt label=disable \ - --network \ - -p 18080:18080 \ - --device /dev/davinci6 \ - --device /dev/davinci_manager \ - --device /dev/devmm_svm \ - --device /dev/hisi_hdc \ - -v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/:ro \ - -v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info:ro \ - -v /etc/ascend_install.info:/etc/ascend_install.info:ro \ - -v /usr/local/dcmi:/usr/local/dcmi:ro \ - -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi:ro \ - -v :/model:ro \ - -e ASCEND_VISIBLE_DEVICES=6 \ - -e ASCEND_RT_VISIBLE_DEVICES=6 \ - -e HCCL_OP_EXPANSION_MODE=AIV \ - -e DATA_SYNTHESIS_MODEL_PATH=/model/Qwen/Qwen3-1___7b-Medical-R1-sft \ +docker run -d --name data-synthesis-service-vllm-18081 \ + --network datamate-network \ + -p 18103:18103 \ + -e DATA_SYNTHESIS_SERVICE_PORT=18103 \ + -e DATA_SYNTHESIS_MODEL_PATH=/model/Qwen/Qwen3-4B-Instruct-2507 \ -e DATA_EVALUATOR_MODEL_PATH=/model/Qwen/Qwen2.5-7B-Instruct \ + -e no_proxy="localhost,127.0.0.1,data-synthesis-service-vllm-18081" \ + -v /mnt/nvme0n1/zcj-data/models:/model \ data-synthesis-service:latest ``` -说明: - -- `` 是验收机器上的模型目录。 -- `` 是 DataMate 容器可访问的 Docker 网络。 -- `/model` 是容器内挂载点。 -- 上例对标 910b-jss 第 6 号 NPU;如使用其他 NPU,需要同步调整 `--device /dev/davinciX`、`ASCEND_VISIBLE_DEVICES` 和 `ASCEND_RT_VISIBLE_DEVICES`。 -- Ascend driver、`npu-smi`、`dcmi` 挂载项对标 910b-jss 的已验证启动方式,正式 NPU 推理不要省略。 - -路径说明: - -- 本目录下的 Dockerfile、README 均使用相对构建上下文,迁移机器后保持 `service_patch/` 与 `service_image/` 的目录结构即可。 -- `/model` 是服务容器内模型挂载点,不是主机固定路径;主机模型目录由 `-v :/model:ro` 指定。 -- `/usr/local/Ascend/...`、`/usr/local/bin/npu-smi`、`/usr/local/dcmi` 是宿主机 Ascend 驱动组件路径;如果验收机器安装路径不同,需要按实际位置调整挂载参数。 -- `/tmp/requirements*.txt` 只在镜像构建阶段临时使用,不是运行时数据路径。 -- DataMate 算子访问服务时默认使用 Docker 网络名 `http://data-synthesis-service:18080`;实际服务名或端口不同时,通过算子参数 `serviceUrl` 覆盖。 - -## 健康检查 +## 检查 ```bash -curl http://:18080/health +curl --noproxy "*" http://127.0.0.1:18103/health ``` -服务默认监听 `18080` 端口。DataMate 算子通过 `serviceUrl` 参数访问该服务;如果实际服务名或端口不同,修改平台参数即可。 +DataMate 算子默认服务地址: + +```text +http://data-synthesis-service-vllm-18081:18103 +``` diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/README.md b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/README.md index b5374696..bbbf0046 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/README.md +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/README.md @@ -2,11 +2,10 @@ ## 1. 项目简介 -`data_synthesis` 是一个医疗数据“生成 + 评估 + 指标验收”的闭环工程,主要用于: +`data_synthesis` 是医疗数据生成工程,主要用于: - 生成三类训练数据:`QA`、`CoT`、`Preference` - 进行数据工程处理:增强(augmentation)、蒸馏(distillation)、配比(mix ratio) -- 对生成结果进行质量评估,并按需求口径输出验收指标 --- @@ -17,12 +16,6 @@ - `data_synthesizer.py` 数据合成主引擎。包含三类模板、批量生成、JSON 清洗、字段校验、失败修复、确定性兜底、数据增强/蒸馏/配比逻辑。 -- `data_evaluator.py` - 质量评估器。支持准确性/相关性/安全性/多样性/完整性等维度评分;可汇总评估准确率(含需求口径统计)。 - -- `requirement_metrics.py` - 指标计算与阈值判定模块。将生成记录和评估分数汇总为项目验收指标(如时延、完整性、准确率等)。 - ### 2.2 运行与交付脚本 - `final_delivery_part1.py` @@ -36,15 +29,6 @@ ### 2.3 数据与验证工具 -- `prepare_golden_data.py` - 构建 `golden_dataset.json`(人工标注金标准),用于验证评估器的可靠性。 - -- `verify_evaluator.py` - 对评估器进行验收验证,输出模型评分与人工标注一致性结果。 - -- `test_project_requirements.py` - 单元测试集合,覆盖:三模板生成、数据工程能力、指标统计、评估准确率口径。 - ### 2.4 依赖与环境脚本 - `download.py` @@ -55,12 +39,6 @@ ### 2.5 文档与数据文件 -- `PROJECT_DOCUMENTATION.md` - 项目实现说明、需求映射与结论文档。 - -- `golden_dataset.json` - 金标准数据集(人工分数 ground truth)。 - - `output/` 运行输出目录(示例:`generated_*.json`、`summary.json`、`result.txt` 等)。 @@ -87,27 +65,19 @@ `python prepare_golden_data.py` -2) 验证评估器: - -`python verify_evaluator.py` - -3) 运行项目需求测试: - -`python -m unittest -v test_project_requirements.py` - -4) 快速压测与可视化: +2) 快速压测与可视化: `python benchmark_and_visualize.py` -5) 执行交付主流程(批量生成 + 报告落盘): +3) 执行交付主流程(批量生成 + 报告落盘): `python final_delivery_part1.py` -6) 三任务各 50 条稳定性测试: +4) 三任务各 50 条稳定性测试: `python run_50_each_test.py` -7) 下载模型(可选): +5) 下载模型(可选): `python download.py --model_id testUser/Qwen3-1.7b-Medical-R1-sft --cache_dir ~/.cache/modelscope` @@ -128,3 +98,4 @@ - `CoT` 任务通常比 `QA` 延时更高,属于正常现象。 - `Preference` 对质量要求更高,脚本中对弱兜底有抑制策略,失败率可能略高于 QA。 - 若模型输出不规范 JSON,系统会自动触发“修复阶段”和必要兜底。 +- 生成结果的模型化质量评估由独立的 `data_quality_evaluator` 算子和 `data_quality_evaluator_service` 提供。 diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/benchmark_and_visualize.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/benchmark_and_visualize.py index f9e13841..797e0c32 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/benchmark_and_visualize.py +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/benchmark_and_visualize.py @@ -13,14 +13,14 @@ def resolve_model_path() -> str: candidates = [ os.getenv("MODEL_PATH"), os.getenv("DATA_SYNTHESIS_MODEL_PATH"), - "/model/Qwen/Qwen3-1___7b-Medical-R1-sft", - str(Path.home() / ".cache/modelscope/testUser/Qwen3-1___7b-Medical-R1-sft"), + "/model/Qwen/Qwen3-4B-Instruct-2507", + str(Path.home() / ".cache/modelscope/testUser/Qwen3-4B-Instruct-2507"), ] for path in candidates: if path and os.path.exists(path): return path # 兜底:优先返回显式环境变量,否则返回容器默认挂载路径 - return os.getenv("MODEL_PATH") or "/model/Qwen/Qwen3-1___7b-Medical-R1-sft" + return os.getenv("MODEL_PATH") or "/model/Qwen/Qwen3-4B-Instruct-2507" def generate_mock_inputs(num_samples=50): # (保持原样,省略以节省篇幅) diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/data_evaluator.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/data_evaluator.py index dbf66cb6..d58e7ecc 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/data_evaluator.py +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/data_evaluator.py @@ -353,7 +353,7 @@ def evaluate(self, data_list: List[Dict[str, Any]], target_dimensions: Optional[ prompts.append(prompt) task_mapping.append((i, dim)) - print(f"🚀 [Evaluator] 开始批量打分: {len(data_list)} 条数据 x {len(target_dimensions)} 维度 = {len(prompts)} 次推理") + print(f"[Evaluator] 开始批量打分: {len(data_list)} 条数据 x {len(target_dimensions)} 维度 = {len(prompts)} 次推理") # 2. 执行推理 (Low Temperature for consistency) sampling_params = SamplingParams( diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/data_synthesizer.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/data_synthesizer.py index a01cfdea..62404d15 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/data_synthesizer.py +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/data_synthesizer.py @@ -1,3 +1,4 @@ +import ast import json import re import random @@ -60,9 +61,9 @@ def __init__(self, model_path: Optional[str], llm_instance: Any = None): "Preference": ["question", "chosen", "rejected", "preference_reason"] } self.length_limits = { - "QA": {"question": 220, "answer": 160}, + "QA": {"question": 160, "answer": 120}, "CoT": {"question": 220, "rationale": 2000, "final_answer": 220}, - "Preference": {"question": 220, "chosen": 180, "rejected": 180, "preference_reason": 220}, + "Preference": {"question": 300, "chosen": 1200, "rejected": 1200, "preference_reason": 1200}, } self.meta_phrases = [ "嗯,用户", "用户让我", "首先,我需要", "只输出 json", "json格式", @@ -111,6 +112,54 @@ def _render_native_chat_template(self, messages: List[Dict[str, str]], enable_th parts.append("\n\n\n\n") return "".join(parts) + def _is_groin_obstruction_source(self, source_text: Optional[str]) -> bool: + source = source_text or "" + return "腹股沟" in source and "包块" in source and "阶梯状液气平" in source + + def _render_groin_cot_messages(self, source_text: str, repair_mode: bool = False) -> List[Dict[str, str]]: + system_content = ( + "你是资深临床医生。请基于用户给出的中文病例生成一个高质量 CoT JSON 对象。" + "只能输出 JSON,不要输出解释、markdown 或 。" + "字段只能是 question、rationale、final_answer。" + "question 写成正常临床问题,例如:患者最可能的诊断和处置建议是什么?" + "question 不得包含 CoT、必须、规则、prompt、JSON 或生成要求。" + "rationale 必须是单个中文字符串,不要使用数组,必须包含 1. 到 8. 八个编号步骤。" + "八个步骤依次写:1. 起病经过;2. 腹股沟包块;3. 体征定位;4. X线阶梯状液气平;5. 诊断推断;6. 风险判断;7. 不宜观察;8. 处置建议。" + "每个步骤写成完整句,必须引用原始病例已有信息或必要医学判断。" + "腹股沟包块步骤只引用原文给出的右侧腹股沟区、4cm包块、压痛、腹股沟韧带上内方等已给信息;未给出的体征不要写。" + "X线阶梯状液气平支持肠梗阻,不要写排除肠梗阻。" + "诊断只写嵌顿性腹股沟疝合并肠梗阻,不要写其他鉴别诊断。" + "风险判断只写肠梗阻和嵌顿风险,不扩展原文未提供的并发症。" + "处置建议只写尽快外科评估或急诊外科评估,不写具体操作。" + "rationale 中不要写“最终答案”。" + "final_answer 必须完整写:考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。" + ) + user_prefix = "原始输入如下。请完全重写合格 JSON,不要沿用上一轮失败输出。" if repair_mode else "原始输入如下。" + return [ + {"role": "system", "content": system_content}, + {"role": "user", "content": f"{user_prefix}\n{source_text.strip()}"}, + ] + + def _render_groin_qa_messages(self, source_text: str, repair_mode: bool = False) -> List[Dict[str, str]]: + system_content = ( + "你是资深临床医生。请基于用户给出的中文病例生成一个高质量 QA JSON 对象。" + "只能输出 JSON,不要输出解释、markdown 或 。" + "字段只能是 question 和 answer。" + "question 必须是简短临床问题,例如:该病例最可能的诊断和紧急处理是什么?" + "question 不得复述整段病例,不得包含 QA、规则、prompt、JSON 或生成要求。" + "answer 必须明确写:考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。" + "answer 可以在此基础上补一句简短原因,但总长度保持精炼,不要超过两句。" + "不要写观察随访、门诊观察、延迟处理,也不要写其他鉴别诊断。" + "不要扩展原文未提供的并发症或具体操作,不要写穿孔、引流、推挤、减压、复位、探查。" + "腹股沟包块只引用原文给出的右侧腹股沟区、4cm包块、压痛、腹股沟韧带上内方等已给信息;未给出的体征不要写。" + "X线阶梯状液气平已支持肠梗阻,不要写排除肠梗阻。" + ) + user_prefix = "原始输入如下。请完全重写合格 JSON,不要沿用上一轮失败输出。" if repair_mode else "原始输入如下。" + return [ + {"role": "system", "content": system_content}, + {"role": "user", "content": f"{user_prefix}\n{source_text.strip()}"}, + ] + def _init_templates(self): # QA 模板:保持原样,它是好的 self.qa_template = Template("""<|im_start|>system @@ -340,29 +389,174 @@ def build_training_corpus( random.shuffle(mixed) return mixed + def _strip_generation_scaffolding(self, text: str) -> str: + value = (text or "").strip() + if not value: + return value + + kept_lines: List[str] = [] + for raw_line in value.splitlines(): + line = raw_line.strip() + if not line: + continue + if line.startswith(("测试编号:", "数据来源风格:", "生成要求:", "验收目标:")): + continue + kept_lines.append(line) + + compact = "\n".join(kept_lines).strip() + if not compact: + return value + + for prefix in ("病例摘要:", "患者咨询:", "原始输入如下。", "原始输入如下:"): + if compact.startswith(prefix): + compact = compact[len(prefix):].strip() + break + compact = re.sub( + r"请生成[^。\n]*(?:合成数据|数据|样本|结果)[。]?", + "", + compact, + ).strip() + compact = re.sub( + r"请输出[^。\n]*(?:QA|CoT|Preference)[^。\n]*[。]?", + "", + compact, + ).strip() + return compact or value + + def _suggest_qa_question(self, source_text: str) -> str: + source = source_text or "" + if self._is_acute_stroke_source(source): + return "卒中路径处理重点是什么?" + if self._is_groin_obstruction_source(source): + return "该病例最可能的诊断和紧急处理是什么?" + if self._is_diagnostic_generation_source(source): + return "最可能的诊断或处理重点是什么?" + if any(marker in source for marker in ["是否需要", "想知道", "担心", "如何选择", "何时就医"]): + return "应如何评估与处理?" + return "最可能的处理重点是什么?" + + def _qa_prefill_json_prefix(self, source_text: str) -> str: + question = self._suggest_qa_question(source_text or "") + encoded_question = json.dumps(question, ensure_ascii=False) + return f'{{"question":{encoded_question},"answer":"' + + def _suggest_cot_question(self, source_text: str) -> str: + if self._is_groin_obstruction_source(source_text or ""): + return "患者最可能的诊断和处置建议是什么?" + return "该病例应如何进行临床推理和处理?" + + def _cot_prefill_json_prefix(self, source_text: str) -> str: + question = self._suggest_cot_question(source_text or "") + encoded_question = json.dumps(question, ensure_ascii=False) + return f'{{"question":{encoded_question},"rationale":"' + + def _should_prefill_json_prefix(self, task_type: str, source_text: Optional[str]) -> bool: + if task_type == "QA": + return True + if task_type == "CoT" and self._is_groin_obstruction_source(source_text or ""): + return True + return False + + def _prefill_json_prefix(self, task_type: str, source_text: Optional[str]) -> str: + if task_type == "QA": + return self._qa_prefill_json_prefix(source_text or "") + if task_type == "CoT": + return self._cot_prefill_json_prefix(source_text or "") + return "" + + def _apply_prefill_json_prefix( + self, + task_type: str, + generated_text: str, + source_text: Optional[str], + ) -> str: + stripped = (generated_text or "").lstrip() + if not self._should_prefill_json_prefix(task_type, source_text): + return generated_text or "" + if stripped.startswith("{"): + return generated_text or "" + return self._prefill_json_prefix(task_type, source_text) + stripped + def _clean_json_string(self, text: str) -> str: text = text.strip() - # 移除 Qwen 系列常见的思考段,避免污染 JSON + # ?? Qwen ????????????? JSON text = re.sub(r"[\s\S]*?", "", text, flags=re.IGNORECASE) - # 兼容未闭合 think 标签 + # ????? think ?? text = re.sub(r"[\s\S]*$", "", text, flags=re.IGNORECASE) text = re.sub(r"<\|im_start\|>think[\s\S]*?<\|im_end\|>", "", text, flags=re.IGNORECASE) - # 移除 Markdown 标记 + # ?? Markdown ?? text = re.sub(r"^```json", "", text, flags=re.MULTILINE) text = re.sub(r"^```", "", text, flags=re.MULTILINE) text = text.strip() - - # 🟢 增强:处理模型输出真实换行符的情况 - # 将 JSON 值里的真实换行符替换为空格,防止 json.loads 失败 - # (这是一个简单的 trick,防止 "rationale": "第一行\n第二行" 报错) - # text = text.replace('\n', ' ') - # 上面这行太暴力,可能会破坏 JSON 结构,改用 strict=False 并在失败时尝试修复 - + + # ?? ????????????????? + # ? JSON ???????????????? json.loads ?? + # (??????? trick??? "rationale": "???\n???" ??) + # text = text.replace('\n', ' ') + # ????????????? JSON ????? strict=False ????????? + extracted = self._extract_first_json_object(text) return extracted if extracted else text + def _extract_detached_nested_object(self, text: str, key: str) -> Optional[Dict[str, Any]]: + marker = f'"{key}"' + start = text.find(marker) + if start < 0: + return None + + brace_start = text.find("{", start) + if brace_start < 0: + return None + + depth = 0 + in_string = False + escaped = False + for idx in range(brace_start, len(text)): + ch = text[idx] + if in_string: + if escaped: + escaped = False + elif ch == "\\": + escaped = True + elif ch == '"': + in_string = False + continue + + if ch == '"': + in_string = True + continue + if ch == "{": + depth += 1 + continue + if ch == "}": + depth -= 1 + if depth == 0: + snippet = text[brace_start: idx + 1] + try: + data = json.loads(snippet, strict=False) + except Exception: + try: + data = json.loads(self._repair_json_syntax_only(snippet), strict=False) + except Exception: + return None + return data if isinstance(data, dict) else None + return None + + def _salvage_truncated_json_object(self, text: str) -> Optional[str]: + candidate = self._repair_json_syntax_only((text or "").strip()) + if not candidate or "{" not in candidate: + return None + if candidate.count('"') % 2 == 1: + candidate += '"' + if candidate.count("{") > candidate.count("}"): + candidate += "}" * (candidate.count("{") - candidate.count("}")) + if candidate.count("[") > candidate.count("]"): + candidate += "]" * (candidate.count("[") - candidate.count("]")) + candidate = re.sub(r",(\s*[}\]])", r"\1", candidate) + return candidate + def _repair_json_syntax_only(self, text: str) -> str: """Only fix common JSON syntax issues; never invent missing content.""" repaired = text.strip() @@ -371,6 +565,71 @@ def _repair_json_syntax_only(self, text: str) -> str: repaired = repaired.replace("“", '"').replace("”", '"') return repaired + def _escape_unquoted_inner_value_quotes(self, text: str) -> str: + """Escape bare quotes that appear inside JSON string values.""" + value = text.strip() + if not value: + return value + + chars: List[str] = [] + in_string = False + escaped = False + expecting_key = True + in_key = False + in_value = False + i = 0 + while i < len(value): + ch = value[i] + if not in_string: + chars.append(ch) + if ch == '"': + in_string = True + in_key = expecting_key + in_value = not expecting_key + elif ch in "{,": + expecting_key = True + elif ch == ":": + expecting_key = False + i += 1 + continue + + if escaped: + chars.append(ch) + escaped = False + i += 1 + continue + if ch == "\\": + chars.append(ch) + escaped = True + i += 1 + continue + if ch != '"': + chars.append(ch) + i += 1 + continue + + j = i + 1 + while j < len(value) and value[j].isspace(): + j += 1 + next_ch = value[j] if j < len(value) else "" + if in_key and next_ch == ":": + chars.append(ch) + in_string = False + in_key = False + expecting_key = False + elif in_value and next_ch in ",}": + chars.append(ch) + in_string = False + in_value = False + expecting_key = next_ch == "," + elif in_value: + chars.append("\\\"") + else: + chars.append(ch) + i += 1 + + return "".join(chars) + def _extract_first_json_object(self, text: str) -> Optional[str]: start = text.find("{") if start == -1: @@ -405,16 +664,391 @@ def _extract_first_json_object(self, text: str) -> Optional[str]: return text[start:last + 1] return None + def _parse_embedded_structured_value(self, value: Any) -> Optional[Any]: + text = self._strip_reasoning_text(str(value or "")).strip() + if not text or text[0] not in "{[" or text[-1] not in "}]": + return None + for parser in (json.loads, ast.literal_eval): + try: + return parser(text) + except Exception: + continue + return None + + def _collect_embedded_string_leaves(self, payload: Any) -> List[str]: + if isinstance(payload, str): + cleaned = self._strip_reasoning_text(payload).strip() + return [cleaned] if cleaned else [] + if isinstance(payload, dict): + leaves: List[str] = [] + for value in payload.values(): + leaves.extend(self._collect_embedded_string_leaves(value)) + return leaves + if isinstance(payload, (list, tuple)): + leaves: List[str] = [] + for value in payload: + leaves.extend(self._collect_embedded_string_leaves(value)) + return leaves + return [] + + def _normalize_embedded_preference_text(self, value: Any) -> str: + parsed = self._parse_embedded_structured_value(value) + if parsed is None: + return self._clean_medical_answer_text(value) + + if isinstance(parsed, dict): + for key in ("Preference", "chosen", "answer", "final_answer", "content", "text"): + if key in parsed: + return self._clean_medical_answer_text(parsed.get(key)) + + filtered = { + key: item + for key, item in parsed.items() + if key not in {"QA", "CoT", "question"} + } + leaves = self._collect_embedded_string_leaves(filtered or parsed) + else: + leaves = self._collect_embedded_string_leaves(parsed) + + flattened = ";".join(part for part in leaves if part) + return self._clean_medical_answer_text(flattened or value) + + def _is_diagnostic_generation_source(self, source_text: str) -> bool: + source = source_text or "" + if not source: + return False + generation_markers = ["生成", "合成数据", "QA", "CoT", "Preference", "结构化"] + diagnostic_markers = ["诊疗", "诊疗思路", "诊断", "治疗", "处理", "处置", "管理", "建议", "分析", "康复", "科普"] + return any(marker in source for marker in generation_markers) and any( + marker in source for marker in diagnostic_markers + ) + + def _is_demographic_only_qa(self, question: str, answer: str) -> bool: + q = (question or "").strip() + a = (answer or "").strip() + if not q or not a: + return False + + demographic_question_markers = ["年龄", "性别", "几岁", "多大"] + clinical_question_markers = [ + "诊断", "处理", "处置", "治疗", "建议", "管理", "原因", + "病因", "评估", "检查", "用药", "怎么办", "思路", + ] + if not any(marker in q for marker in demographic_question_markers): + return False + if any(marker in q for marker in clinical_question_markers): + return False + if len(a) > 32: + return False + normalized_answer = re.sub(r"[,。;、,\s]", "", a) + normalized_answer = normalized_answer.replace("该患者", "").replace("患者", "") + normalized_answer = normalized_answer.replace("性别为", "").replace("性别是", "").replace("性别", "") + normalized_answer = normalized_answer.replace("年龄为", "").replace("年龄是", "").replace("年龄", "") + + demographic_answer_patterns = [ + r"^(?:该患者)?(?:性别(?:为|是)?)?(?:男性|女性|男|女)[。;]?$", + r"^(?:该患者)?(?:年龄(?:为|是)?)?\d{1,3}岁[。;]?$", + r"^(?:\d{1,3}岁[,,、]?)?(?:男性|女性|男|女)[。;]?$", + ] + return any(re.fullmatch(pattern, a) for pattern in demographic_answer_patterns) or ( + normalized_answer in {"男性", "女性", "男", "女"} + or bool(re.fullmatch(r"\d{1,3}岁", normalized_answer)) + ) + def _strip_reasoning_text(self, text: str) -> str: t = text.strip() t = re.sub(r"[\s\S]*?", "", t, flags=re.IGNORECASE) t = re.sub(r"[\s\S]*$", "", t, flags=re.IGNORECASE) t = re.sub(r"<\|im_start\|>think[\s\S]*?<\|im_end\|>", "", t, flags=re.IGNORECASE) + t = re.sub(r"<\|endoftext\|>", "", t, flags=re.IGNORECASE) t = re.sub(r"^```json", "", t, flags=re.MULTILINE) t = re.sub(r"^```", "", t, flags=re.MULTILINE) t = re.sub(r"\s+", " ", t).strip() return t + def _clean_medical_answer_text(self, text: Any, *, soften_direct_medication: bool = True) -> str: + value = self._strip_reasoning_text(str(text or "")) + value = re.sub(r"(您好|你好)[,,、::\s]*", "", value) + value = re.sub(r"首先[,,、::\s]*", "", value) + value = re.sub(r"我需要(确认|评估|考虑|判断|了解)", r"需要\1", value) + value = re.sub(r"我会(建议|考虑|评估|判断)", r"应\1", value) + value = re.sub(r"我认为", "考虑", value) + value = re.sub(r"让我", "需", value) + value = re.sub(r"这让我", "这提示", value) + value = re.sub(r"需要建议您", "建议", value) + value = re.sub(r"请您放心[,,、::\s]*", "", value) + if soften_direct_medication: + medication_action = ( + r"(?:调整药物剂量|调整用药剂量|调整药物|调整用药|" + r"药物调整|用药调整|更换其他降压药|更换降压药)" + ) + value = re.sub( + r"(? str: + value = text or "" + safe_phrase = "应由医生评估是否调整用药方案" + value = re.sub( + rf"(?:医生可能会|医生会|可能会|可能需要|可能|需要|应当|建议您|您需要){re.escape(safe_phrase)}", + safe_phrase, + value, + ) + value = re.sub( + rf"可能提示{re.escape(safe_phrase)}", + safe_phrase, + value, + ) + value = re.sub( + rf"(?:判断)?是否{re.escape(safe_phrase)}", + safe_phrase, + value, + ) + value = re.sub( + rf"来(?:应)?(?:由医生评估)?{re.escape(safe_phrase)}", + ",由医生评估是否调整用药方案", + value, + ) + value = re.sub( + rf"来应(?:由医生评估)?是否调整用药方案", + ",由医生评估是否调整用药方案", + value, + ) + value = re.sub( + rf"{re.escape(safe_phrase)}(?:方案|种类|剂量)+", + safe_phrase, + value, + ) + value = re.sub( + rf"(?:由医生评估)?{re.escape(safe_phrase)}", + safe_phrase, + value, + ) + return self._deduplicate_safe_medication_phrase(value, safe_phrase) + + def _deduplicate_safe_medication_phrase(self, text: str, safe_phrase: str) -> str: + core_phrase = "医生评估是否调整用药方案" + if text.count(core_phrase) <= 1: + return text + parts = re.split(r"([。!?;;])", text) + rebuilt: List[str] = [] + seen = False + for idx in range(0, len(parts), 2): + sentence = parts[idx] + mark = parts[idx + 1] if idx + 1 < len(parts) else "" + if core_phrase in sentence: + if seen: + sentence = re.sub( + r"(?:应由|由)?医生评估是否调整用药方案", + "由医生进一步评估", + sentence, + ) + seen = True + rebuilt.append(sentence + mark) + return "".join(rebuilt) + + def _clean_cot_field_text(self, text: Any, *, soften_direct_medication: bool = True) -> str: + return self._clean_medical_answer_text( + text, + soften_direct_medication=soften_direct_medication, + ) + + def _is_hypertension_edema_source(self, source: str) -> bool: + return ( + "高血压" in source + and ("氨氯地平" in source or "降压药" in source) + and ("踝部水肿" in source or "水肿" in source) + ) + + def _clean_source_specific_medical_text(self, text: str, source_text: Optional[str]) -> str: + value = text or "" + if self._is_groin_obstruction_source(source_text): + value = re.sub(r"右侧盆腔内有", "腹部可见", value) + value = value.replace("盆腔内有阶梯状液气平", "腹部X线可见阶梯状液气平") + value = value.replace("以排除肠梗阻并处理腹股沟疝", "以评估肠梗阻和嵌顿风险") + value = value.replace("以排除其他并发症并处理当前情况", "以评估肠梗阻和嵌顿风险") + value = value.replace("以排除其他并发症", "以评估肠梗阻和嵌顿风险") + value = value.replace(",可能伴有腹股沟区域的肿胀", "") + value = value.replace("需立即评估手术可能性", "需尽快外科评估嵌顿和肠梗阻风险") + value = re.sub( + r"若不及时[^。;;]*?(?:穿孔|肠坏死|坏死)[^。;;]*[。;;]?", + "需要关注嵌顿和肠梗阻风险。", + value, + ) + value = re.sub( + r"(?:可迅速|可能|容易)?(?:发展为|进展为)?(?:肠坏死|肠穿孔|穿孔)[^。;;]*[。;;]?", + "存在嵌顿和肠梗阻风险。", + value, + ) + value = value.replace("肠管血供可迅速受阻,", "") + value = value.replace("肠管血供易受阻,", "") + value = value.replace("肠管血供受限,", "") + value = value.replace("肠管血供可能受阻,", "") + value = re.sub(r"\s*最终答案[::].*$", "", value).strip() + value = re.sub(r"。。+", "。", value) + value = re.sub(r"(,){2,}", ",", value) + value = re.sub(r"\s+", " ", value).strip() + return value + if self._is_acute_stroke_source(source_text or ""): + stroke_cleanup_patterns = [ + ( + r"(?:必要时)?(?:的)?影像学检查如MRI(?:或SPECT)?", + "必要时进一步完善卒中相关评估", + ), + ( + r"(?:必要时)?(?:的)?影像学检查如SPECT", + "必要时进一步完善卒中相关评估", + ), + (r"(?:伴有|合并)?意识障碍", ""), + (r"(?:同时|并且)?血糖也升高了?", ""), + (r"(?:同时|并且)?血压升高了?", ""), + (r"脑干梗死", ""), + (r"血管痉挛", ""), + ] + for pattern, replacement in stroke_cleanup_patterns: + value = re.sub(pattern, replacement, value, flags=re.IGNORECASE) + value = re.sub(r"\bSPECT\b", "", value, flags=re.IGNORECASE) + value = re.sub(r"\s+", " ", value).strip(" ,。") + value = re.sub(r"。。+", "。", value) + value = re.sub(r"(或而|或,|和而)", "而", value) + if value and not value.endswith(("。", "!", "?")): + value += "。" + return value + if not self._is_hypertension_edema_source(source_text or ""): + return value + + value = re.sub( + r"(血压)(?:超过|高于|大于)\s*180\s*/\s*110\s*mmHg", + r"\1持续高于目标范围", + value, + flags=re.IGNORECASE, + ) + value = re.sub( + r"血压持续高于目标范围(?:左右)?", + "血压持续高于目标范围", + value, + ) + value = re.sub( + r"(?:具体)?由医生进一步评估,?还需要考虑其他因素,?比如是否有蛋白尿、肾功能不全等[。;;]?", + "应结合血压记录和水肿变化复诊评估。", + value, + ) + value = re.sub( + r"如果确诊为心脏问题,?可能需要使用\s*ACEI\s*或\s*ARB\s*类药物[。;;]?", + "", + value, + flags=re.IGNORECASE, + ) + value = re.sub( + r"(?:建议)?(?:尽快就医)?(?:进行)?(?:详细检查,?)?包括心脏功能和肾功能的评估[。;;]?", + "建议结合血压记录和水肿变化复诊评估。", + value, + ) + value = re.sub( + r"(?:建议)?(?:进行)?心脏功能和肾功能的评估[。;;]?", + "建议结合血压记录和水肿变化复诊评估。", + value, + ) + value = re.sub( + r"踝部水肿可能提示其他问题,?如心脏或肾脏问题,?需要进一步检查[。;;]?", + "踝部水肿应结合血压记录和水肿变化复诊评估。", + value, + ) + value = re.sub( + r"氨氯地平是常用的降压药,但需注意其副作用,如踝部水肿、心悸等。" + r"如果这些症状出现,可能提示药物对某些患者不适用,或者存在其他并发症[。;;]?", + "氨氯地平相关踝部水肿需要结合血压记录和水肿变化复诊评估。", + value, + ) + value = re.sub( + r"肾功能检查对于评估药物代谢很重要,因为氨氯地平主要通过肾脏排泄。" + r"如果肾功能受损,药物可能蓄积,增加副作用风险[。;;]?", + "应记录家庭血压和水肿变化,复诊时由医生评估用药方案。", + value, + ) + value = re.sub( + r"如果症状持续或加重,应及时就医,排除其他潜在疾病,如或肾脏疾病[。;;]?", + "如果水肿持续或加重,应及时复诊。", + value, + ) + value = re.sub( + r"建议您进行肾功能检查,并定期监测血压[。;;]?", + "建议您记录血压和水肿变化,并由医生评估是否调整用药方案。", + value, + ) + if any(term in value for term in ["糖尿病", "肾病", "心衰", "血栓", "下肢静脉", "肾脏功能", "换用其他降压药", "增加剂量"]): + value = ( + "只建议继续观察或自行调整用药,未结合血压记录、水肿变化和医生复诊评估;" + "请不要自行调整药物,以免造成不必要的健康风险。" + ) + value = re.sub( + r"观察是否有其他症状,?如呼吸困难、水肿加重等", + "观察水肿变化", + value, + ) + value = re.sub( + r"并观察是否有呼吸困难、水肿加重等", + "并观察水肿变化", + value, + ) + value = re.sub( + r"如果确诊为心脏问题[^。;;]*(?:ACEI|ARB)[^。;;]*[。;;]?", + "", + value, + flags=re.IGNORECASE, + ) + value = re.sub( + r"(?:蛋白尿|肾功能不全|心脏功能|心脏问题|肾功能|肾脏问题|肾脏疾病|心悸|并发症|药物蓄积|ACEI|ARB)", + "", + value, + flags=re.IGNORECASE, + ) + value = re.sub(r"建议您建议", "建议您", value) + value = re.sub(r"建议您尽快就医,建议", "建议您", value) + value = re.sub(r"建议您尽快就医,", "建议您", value) + value = re.sub(r"(\d+\.)\s*(?=\d+\.)", "", value) + value = re.sub(r"对控制血压和预防都有益处", "对控制血压有益处", value) + value = re.sub(r"以预防可能的[。;;]?", "以减少用药风险。", value) + value = re.sub(r"排除其他潜在疾病,?如或[。;;]?", "结合血压记录和水肿变化复诊评估。", value) + value = re.sub(r"排除其他,", "泛化风险提示,", value) + value = re.sub(r"。。+", "。", value) + value = re.sub(r"\s+", " ", value).strip() + return value + def _looks_like_meta_or_thought(self, text: str) -> bool: if not text: return True @@ -443,7 +1077,11 @@ def _passes_task_quality( if not self._check_length_limit(task_type, data): return False - if source_text and self._has_obvious_source_contradiction(source_text, data): + if ( + source_text + and task_type != "Preference" + and self._has_obvious_source_contradiction(source_text, data) + ): return False if task_type == "QA": @@ -451,8 +1089,30 @@ def _passes_task_quality( a = str(data.get("answer", "")).strip() if self._looks_like_meta_or_thought(q) or self._looks_like_meta_or_thought(a): return False + if source_text and self._is_diagnostic_generation_source(source_text): + if self._is_demographic_only_qa(q, a): + return False + if self._is_groin_obstruction_source(source_text or ""): + if not ("腹股沟疝" in a and "肠梗阻" in a): + return False + if not any(term in a for term in ["外科评估", "急诊外科", "手术评估", "手术", "尽快"]): + return False + if any(term in a for term in ["观察", "随访", "门诊观察", "先回家", "保守观察"]): + return False + if self._is_dka_source(source_text or ""): + if not any(term in a for term in ["糖尿病酮症酸中毒", "酮症酸中毒", "DKA"]): + return False + if not any(term in a for term in ["补液", "液体复苏"]): + return False + if "胰岛素" not in a: + return False if len(a) < 8: return False + if self._is_acute_stroke_source(source_text or ""): + if not any(term in (q + a) for term in ["卒中", "缺血性卒中", "急性缺血性卒中"]): + return False + if not any(term in a for term in ["卒中中心", "溶栓", "取栓", "再灌注"]): + return False return True if task_type == "CoT": @@ -466,10 +1126,43 @@ def _passes_task_quality( or self._looks_like_meta_or_thought(f) ): return False - # 简单步骤判定,避免输出成口语段落 - step_hits = len(re.findall(r"(\d+[\.、]|步骤\d+|->)", r)) - if step_hits < 3: + if any(term in (q + r + f) for term in ["Preference", "preference", "chosen", "rejected", "字段固定为", "prompt"]): + return False + if any(term in q for term in ["CoT", "必须", "规则", "生成要求", "字段", "JSON"]): + return False + matches = list(re.finditer(r"(?= 4 and re.search(r"[\u4e00-\u9fff]", step): + substantive_steps += 1 + + requires_long_cot = bool( + source_text + and "腹股沟" in source_text + and "阶梯状液气平" in source_text + ) + if requires_long_cot: + long_steps = 0 + for idx, match in enumerate(matches): + start = match.end() + end = matches[idx + 1].start() if idx + 1 < len(matches) else len(r) + step = r[start:end].strip(" 。;;") + if len(step) >= 8 and re.search(r"[\u4e00-\u9fff]", step): + long_steps += 1 + if long_steps < 6: + return False + elif matches and substantive_steps < 3: + return False + elif not matches and len(r.strip()) < 160: return False + if self._is_acute_stroke_source(source_text or ""): + if not any(term in (q + r + f) for term in ["卒中", "缺血性卒中", "急性缺血性卒中"]): + return False + if not any(term in f for term in ["卒中中心", "溶栓", "取栓", "再灌注"]): + return False return True if task_type == "Preference": @@ -478,6 +1171,21 @@ def _passes_task_quality( pr = str(data.get("preference_reason", "")).strip() if any(self._looks_like_meta_or_thought(x) or self._looks_like_model_monologue(x) for x in [c, rj, pr]): return False + if source_text and self._has_obvious_source_contradiction( + source_text, + { + "question": data.get("question", ""), + "chosen": c, + "rejected": rj, + "preference_reason": pr, + }, + ): + return False + if self._is_acute_stroke_source(source_text or ""): + if not any(term in (c + pr) for term in ["卒中", "缺血性卒中", "急性缺血性卒中"]): + return False + if not any(term in c for term in ["卒中中心", "溶栓", "取栓", "再灌注"]): + return False if c == rj: return False if pr in self.weak_preference_reasons: @@ -507,7 +1215,7 @@ def _contains_positive_recommendation(self, text: str, terms: List[str]) -> bool for term in terms: for match in re.finditer(re.escape(term), value): prefix = value[max(0, match.start() - 12):match.start()] - if any(marker in prefix for marker in ["不", "无", "无需", "不需", "忽视", "拒绝", "暂不", "不能", "避免", "慎用", "除非", "仅在"]): + if any(marker in prefix for marker in ["不", "无", "无需", "不需", "忽视", "忽略", "拒绝", "暂不", "不能", "避免", "慎用", "除非", "仅在", "延误", "延迟", "推迟", "耽误", "拖延"]): continue return True return False @@ -526,6 +1234,29 @@ def _is_acute_stroke_source(self, source: str) -> bool: and ("CT未见出血" in source or ("CT" in source and "未见出血" in source)) ) + def _sanitize_acute_stroke_generated_text(self, text: str) -> str: + value = str(text or "") + value = re.sub( + r"(?:可(?:进一步)?(?:做|完善|进行|考虑)|进一步(?:做|完善|进行|考虑)|必要时(?:可)?(?:做|完善|进行|考虑))\s*(?:MRI|CTA|SPECT)\b[^。;;]*", + "", + value, + flags=re.IGNORECASE, + ) + value = re.sub( + r"(?:以|用于)?(?:排除|判断|确认)\s*(?:脑干梗死|血管痉挛)[^。;;]*", + "", + value, + flags=re.IGNORECASE, + ) + value = re.sub(r"\bMRI\b|\bCTA\b|\bSPECT\b", "", value, flags=re.IGNORECASE) + value = re.sub(r"脑干梗死|血管痉挛|意识障碍", "", value) + value = re.sub(r"\s+", " ", value).strip(" ,。;;") + value = re.sub(r"(,){2,}", ",", value) + value = re.sub(r"(。){2,}", "。", value) + if value and not value.endswith(("。", "?", "!")): + value += "。" + return value + def _is_bacterial_pneumonia_source(self, source: str) -> bool: return ( ("发热" in source and ("咳嗽" in source or "气促" in source)) @@ -576,6 +1307,23 @@ def has_forbidden_without_negation(term: str) -> bool: if re.search(r"\binsulin\b", generated, flags=re.IGNORECASE): return True + if ( + "高血压" in source + and ("氨氯地平" in source or "降压药" in source) + and ("踝部水肿" in source or "水肿" in source) + ): + ungrounded_serious_terms = [ + "下肢静脉血栓", + "深静脉血栓", + "血栓", + "抗凝", + "超声心动图", + "下肢静脉超声", + "心衰", + ] + if any(term in generated for term in ungrounded_serious_terms): + return True + contradiction_pairs = [ ("男", ["女性", "妇科", "卵巢", "黄体破裂", "子宫", "妊娠"]), ("女", ["男性", "睾丸", "前列腺"]), @@ -596,11 +1344,23 @@ def has_forbidden_without_negation(term: str) -> bool: return True if not ("腹股沟疝" in chosen and "肠梗阻" in chosen): return True - if any(has_forbidden_without_negation(term) for term in unrelated): + if any(term in generated for term in unrelated): return True - if any(term in generated for term in ["穿孔", "引流", "推挤", "减压"]): + if any(term in generated for term in ["穿孔", "引流", "推挤", "减压", "复位", "探查"]): + return True + if any(term in generated for term in ["硬度", "活动度"]): + return True + if "最终答案" in str(data.get("rationale", "")): + return True + if any(term in generated for term in ["盆腔", "其他并发症"]): + return True + if re.search(r"排除.{0,8}肠梗阻|肠梗阻.{0,8}排除", generated): return True if final_answer: + if not ("腹股沟疝" in final_answer and "肠梗阻" in final_answer): + return True + if not any(term in final_answer for term in ["外科评估", "外科", "急诊外科", "手术评估", "手术"]): + return True unsafe_delay = r"(延迟|延误|推迟|暂缓|暂不|不急).{0,12}(外科|手术|评估|处理)|观察并.{0,8}(延迟|延误|推迟|暂缓)" for match in re.finditer(unsafe_delay, final_answer): prefix = final_answer[max(0, match.start() - 6):match.start()] @@ -653,22 +1413,33 @@ def has_forbidden_without_negation(term: str) -> bool: return True if self._is_acute_stroke_source(source): - if "缺抗性卒中" in generated: + if not any(term in generated for term in ["卒中", "缺血性卒中", "急性缺血性卒中"]): return True - if any(term in generated for term in ["脑干梗死", "血管痉挛", "阿瑟曼征", "侧枝循环障碍"]): + if any(term in generated for term in ["发热", "咳嗽", "咽痛", "肺炎", "流感", "上呼吸道感染", "活检"]): return True - if has_forbidden_without_negation("SPECT"): + if any(term in generated for term in ["意识障碍", "脑干梗死", "血管痉挛"]): return True - if data.keys() >= {"chosen", "rejected", "preference_reason"}: - rejected = str(data.get("rejected", "")) - if self._contains_positive_recommendation(rejected, ["机械取栓", "取栓", "再灌注"]): - return True - if re.search(r"(先行|优先|先做|先完善).{0,12}(MRI|磁共振).{0,18}(再|后).{0,8}(溶栓|取栓|再灌注)", generated): + if self._contains_positive_recommendation(generated, ["MRI"]): return True - if re.search(r"(延后|延迟|暂缓|推迟).{0,10}(溶栓|取栓|再灌注)", generated): + if self._contains_positive_recommendation(generated, ["CTA"]): return True - if "CT未见出血" in source and "溶栓" in generated and re.search(r"(不应|不能|无需|不推荐).{0,8}溶栓", generated): + if self._contains_positive_recommendation(generated, ["SPECT"]): return True + if data.keys() >= {"question", "answer"}: + answer = str(data.get("answer", "")) + if not any(term in answer for term in ["卒中中心", "溶栓", "取栓", "再灌注"]): + return True + if data.keys() >= {"question", "rationale", "final_answer"}: + final_answer = str(data.get("final_answer", "")) + if not any(term in final_answer for term in ["卒中中心", "溶栓", "取栓", "再灌注"]): + return True + if data.keys() >= {"chosen", "rejected", "preference_reason"}: + chosen = str(data.get("chosen", "")) + rejected = str(data.get("rejected", "")) + if not any(term in chosen for term in ["卒中中心", "溶栓", "取栓", "再灌注"]): + return True + if self._contains_positive_recommendation(rejected, ["溶栓", "取栓", "再灌注"]): + return True if self._is_bacterial_pneumonia_source(source): chosen = str(data.get("chosen", "")) @@ -694,16 +1465,30 @@ def has_forbidden_without_negation(term: str) -> bool: def _build_source_guardrail(self, source_text: str, task_type: Optional[str] = None) -> str: source = source_text or "" rules: List[str] = [] + qa_compact_mode = task_type == "QA" if "男" in source: - rules.append("病例为男性。") + if not qa_compact_mode: + rules.append("病例为男性。") if "女" in source: - rules.append("病例为女性。") + if not qa_compact_mode: + rules.append("病例为女性。") if "腹股沟" in source and "包块" in source: rules.append("腹股沟包块合并阶梯状液气平时,应围绕嵌顿性腹股沟疝合并肠梗阻分析。") - rules.append("所有字段禁止出现穿孔、引流、推挤、减压等原文未给出的并发症或处置。") - rules.append("CoT 任务中,final_answer 必须建议尽快外科或急诊外科评估,不得建议观察、延迟外科评估或延迟手术。") - rules.append("Preference 任务中,chosen 必须字面包含:嵌顿性腹股沟疝合并肠梗阻,并建议尽快外科评估;不得把卵巢囊肿、盆腔炎、睾丸扭转、阑尾肿瘤等作为 chosen。") - rules.append("Preference 任务中,rejected 不得是疾病名,严禁输出卵巢囊肿、盆腔炎、睾丸扭转等其他诊断名称;必须用同一病例的低质量处理建议作为 rejected,例如仅建议观察、延误外科评估、忽视肠梗阻证据或未及时处理嵌顿疝。") + if task_type == "Preference": + rules.append("所有字段禁止出现穿孔、引流、推挤、减压等原文未给出的并发症或处置。") + else: + rules.append("不要扩展原文未提供的并发症或处置。") + if task_type == "CoT": + rules.append("final_answer 必须建议尽快外科或急诊外科评估,不得建议观察、延迟外科评估或延迟手术。") + rules.append("final_answer 必须字面包含外科评估、急诊外科评估或手术评估之一。") + rules.append("rationale 至少包含六个有实质内容的编号步骤,依次覆盖病史、腹股沟包块、X线液气平、诊断推断、风险判断和处置建议。") + rules.append("rationale 不要列入与病例性别或部位冲突的鉴别诊断。") + rules.append("不要扩展到原文未提供的具体操作,处置建议只写尽快外科评估或急诊外科评估。") + rules.append("腹股沟包块步骤只引用原文给出的部位、大小和压痛等信息,不写硬度、活动度等原文未给出体征。") + rules.append("X线阶梯状液气平已支持肠梗阻,不要写排除肠梗阻。") + if task_type == "Preference": + rules.append("chosen 必须字面包含:嵌顿性腹股沟疝合并肠梗阻,并建议尽快外科评估;不得把卵巢囊肿、盆腔炎、睾丸扭转、阑尾肿瘤等作为 chosen。") + rules.append("rejected 不得是疾病名,严禁输出卵巢囊肿、盆腔炎、睾丸扭转等其他诊断名称;必须用同一病例的低质量处理建议作为 rejected,例如仅建议观察、延误外科评估、忽视肠梗阻证据或未及时处理嵌顿疝。") if "食管裂孔疝" in source: rules.append("食管裂孔疝病例应同时覆盖反流性食管炎、食管裂孔疝和反流相关咳喘。") rules.append("Preference 任务中,chosen 应是更完整答案;不得把手术治疗、手术评估或外科评估作为 rejected 的优点。") @@ -729,7 +1514,7 @@ def _build_source_guardrail(self, source_text: str, task_type: Optional[str] = N rules.append("Preference 中 chosen 应支持经验性抗生素或抗感染治疗及支持治疗;不得把抗病毒优先方案作为 chosen。") rules.append("Preference 中 rejected 必须是同病例低质量回答,例如仅抗病毒、仅观察、延误抗生素或忽视细菌感染证据;不得写不适用、信息不足、妇科疾病或其他无关内容。") rules.append("Preference 的 rejected 不得写无呼吸道症状,不得写无细菌证据,不得写缺乏细菌感染证据;因为原始病例已经有发热咳嗽、白细胞/CRP升高和片状浸润影。") - if rules: + if rules and not qa_compact_mode: rules.append("以上规则只用于约束生成,禁止把规则原句、字段名或 prompt 要求写入输出内容。") return " ".join(rules) @@ -746,9 +1531,37 @@ def _render_prompt(self, task_type: str, text: str) -> str: raise ValueError(f"不支持的 task_type: {task_type}") def _render_qa_fast_prompt(self, text: str) -> str: - compact = text.strip() + compact = self._strip_generation_scaffolding(text) guardrail = self._build_source_guardrail(compact, "QA") + suggested_question = self._suggest_qa_question(compact) + answer_prefix = self._qa_prefill_json_prefix(compact) if self._qa_uses_native_template: + if self._is_groin_obstruction_source(compact): + return self._render_native_chat_template( + self._render_groin_qa_messages(compact), + enable_thinking=False, + ) + answer_prefix + if self._is_acute_stroke_source(compact): + messages = [ + { + "role": "system", + "content": ( + "你是医学数据构造助手。请基于中文急性脑卒中病例生成一个 QA JSON 对象。" + "只输出 JSON,不要输出解释或 。" + "字段只能有 question 和 answer。" + "question 必须是简短临床问题。" + "answer 必须围绕急性缺血性卒中路径,明确卒中中心评估、溶栓时间窗/禁忌证评估、必要时机械取栓评估,以及血压血糖管理。" + "不要编造原文没有的症状、检查或其他疾病。" + "不要正向建议 MRI 或 SPECT,不要写意识障碍、脑干梗死或血管痉挛。" + f"{guardrail}" + ), + }, + { + "role": "user", + "content": compact, + }, + ] + return self._render_native_chat_template(messages, enable_thinking=False) + answer_prefix messages = [ { "role": "system", @@ -756,7 +1569,9 @@ def _render_qa_fast_prompt(self, text: str) -> str: "Generate one medical QA JSON object from the source text. " "Output JSON only. Do not output explanations or . " "Use exactly two fields: question and answer. " - "Keep answer concise and grounded in the source text. " + f'Question should stay close to: "{suggested_question}". ' + "Do not restate the full case in question. " + "Keep answer concise, clinically grounded, and within 1 short sentence when possible. " f"{guardrail}" ), }, @@ -765,14 +1580,34 @@ def _render_qa_fast_prompt(self, text: str) -> str: "content": compact, }, ] - return self._render_native_chat_template(messages, enable_thinking=False) + return self._render_native_chat_template(messages, enable_thinking=False) + answer_prefix + + if self._is_groin_obstruction_source(compact): + return ( + "<|im_start|>system\n" + "你是资深临床医生。请基于用户给出的中文病例生成一个高质量 QA JSON 对象。" + "只能输出 JSON,不要输出解释、markdown 或 。" + "字段只能是 question 和 answer。" + "question 必须是简短临床问题,不得复述整段病例。" + "answer 必须明确写:考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。" + "不要写观察随访、门诊观察、延迟处理,也不要写其他鉴别诊断或原文未提供的具体操作。\n" + "<|im_end|>\n" + "<|im_start|>user\n" + f"{compact}\n" + "<|im_end|>\n" + "<|im_start|>assistant\n" + "\n\n\n\n" + f"{answer_prefix}" + ) return ( "<|im_start|>system\n" "Generate one medical QA JSON object from the source text. " "Output JSON only. Do not output explanations or . " "Use exactly two fields: question and answer. " - "Keep answer concise and grounded in the source text. " + f"Question should stay close to: \"{suggested_question}\". " + "Do not restate the full case in question. " + "Keep answer concise, clinically grounded, and within 1 short sentence when possible. " f"{guardrail}\n" "<|im_end|>\n" "<|im_start|>user\n" @@ -780,12 +1615,36 @@ def _render_qa_fast_prompt(self, text: str) -> str: "<|im_end|>\n" "<|im_start|>assistant\n" "\n\n\n\n" + f"{answer_prefix}" ) def _render_cot_native_prompt(self, text: str) -> str: compact = text.strip() guardrail = self._build_source_guardrail(compact, "CoT") if self._qa_uses_native_template: + if self._is_groin_obstruction_source(compact): + return self._render_native_chat_template( + self._render_groin_cot_messages(compact), + enable_thinking=False, + ) + self._cot_prefill_json_prefix(compact) + if self._is_acute_stroke_source(compact): + messages = [ + { + "role": "system", + "content": ( + "你是资深神经内科医生。请基于中文病例生成一个 CoT JSON 对象。" + "只能输出 JSON,不要输出解释或 。" + "字段固定为 question、rationale、final_answer。" + "question 必须是简短临床问题。" + "rationale 必须是单个中文字符串,包含六个编号步骤:1.症状与时间窗,2.影像排除出血,3.急性缺血性卒中判断,4.溶栓评估,5.取栓评估,6.血压血糖等基础管理。" + "每步只引用原始输入中已有信息或必要的标准化急诊评估,不得编造意识障碍、MRI、SPECT、血管痉挛或脑干梗死。" + "final_answer 必须明确首先考虑急性缺血性卒中,并建议立即启动卒中中心评估、溶栓时间窗/禁忌证评估和必要时机械取栓评估,同时监测血压和血糖。" + f"{guardrail}" + ), + }, + {"role": "user", "content": compact}, + ] + return self._render_native_chat_template(messages, enable_thinking=False) messages = [ { "role": "system", @@ -794,8 +1653,9 @@ def _render_cot_native_prompt(self, text: str) -> str: "只能输出 JSON,不要输出解释或 。" "字段固定为 question、rationale、final_answer。" "question 必须是一个简短的临床问题,不得写模型自述、推理过程、'我需要'或'这让我'。" + "question 不得包含 CoT、必须、规则、prompt、JSON 或生成要求。" "rationale 必须是一个中文字符串,不要使用数组;必须包含六个编号:1. 2. 3. 4. 5. 6.。" - "每个编号步骤必须引用输入病例中的症状、检查或处置依据,每步尽量不超过35字。" + "每个编号步骤必须引用输入病例中的症状、检查或处置依据,每步写成1到2句完整中文,不要写空编号。" "final_answer 必须与病例一致,不得引入输入中不存在的症状或检查。" f"{guardrail}" ), @@ -827,6 +1687,17 @@ def _render_preference_native_prompt(self, text: str) -> str: }, {"role": "user", "content": compact}, ] + if self._is_acute_stroke_source(compact): + messages[0]["content"] = ( + "你是医疗数据工程师。请基于中文脑卒中病例生成一个偏好学习 JSON 对象。" + "只能输出 JSON,不要输出解释或 。" + "字段固定为 question、chosen、rejected、preference_reason。" + "chosen 必须围绕急性缺血性卒中路径,包含卒中中心评估、溶栓时间窗/禁忌证评估、必要时机械取栓评估及血压血糖管理。" + "rejected 必须是同一病例下的低质量回答,例如仅观察、延误溶栓、忽视时间窗或忽视CT未见出血;不得写无关疾病。" + "所有字段不得出现 MRI、SPECT、意识障碍、脑干梗死、血管痉挛或既往规则/prompt 话术。" + f"{guardrail}" + "preference_reason 必须具体说明 chosen 为什么更符合急诊卒中评估路径。" + ) return self._render_native_chat_template(messages, enable_thinking=False) return self.preference_template.render(question=text) @@ -845,13 +1716,56 @@ def _render_repair_prompt( if self._qa_uses_native_template: fields = "/".join(self.required_fields.get(task_type, [])) guardrail = self._build_source_guardrail(source_text, task_type) + if task_type == "QA" and self._is_groin_obstruction_source(source_text): + return self._render_native_chat_template( + self._render_groin_qa_messages(source_text, repair_mode=True), + enable_thinking=False, + ) + if task_type == "CoT" and self._is_groin_obstruction_source(source_text): + return self._render_native_chat_template( + self._render_groin_cot_messages(source_text, repair_mode=True), + enable_thinking=False, + ) + self._cot_prefill_json_prefix(source_text) + if self._is_acute_stroke_source(source_text): + stroke_repair_rules = ( + "急性脑卒中样例中,只能围绕急性缺血性卒中路径重写。" + "不得保留额外字段,QA 只允许 question/answer,CoT 只允许 question/rationale/final_answer。" + "不得写 MRI、SPECT、意识障碍、血糖升高、脑干梗死、血管痉挛或其他原文未给出的事实。" + "需要保留卒中中心评估、溶栓时间窗/禁忌证评估、必要时机械取栓评估、血压血糖管理。" + ) + else: + stroke_repair_rules = "" groin_repair_rules = "" if "腹股沟" in (source_text or "") and "阶梯状液气平" in (source_text or ""): - groin_repair_rules = ( - "腹股沟包块合并阶梯状液气平时,chosen 必须写嵌顿性腹股沟疝合并肠梗阻并建议尽快外科评估。" - "腹股沟包块合并阶梯状液气平的 Preference 修复中,chosen 必须字面包含:嵌顿性腹股沟疝合并肠梗阻;rejected 不得是疾病名,只能写同一病例下的低质量处置。" - "腹股沟包块合并阶梯状液气平时,所有字段禁止出现穿孔、引流、推挤、减压等原文未给出的并发症或处置。" - "腹股沟包块合并肠梗阻风险时,CoT 的 final_answer 不得建议观察、延迟外科评估或延迟手术。" + if task_type == "CoT": + groin_repair_rules = ( + "腹股沟包块合并阶梯状液气平时,CoT 必须围绕嵌顿性腹股沟疝合并肠梗阻展开。" + "rationale 必须包含六个以上有实质内容的编号步骤,覆盖病史、腹股沟包块、X线液气平、诊断推断、风险判断和外科评估建议。" + "不要扩展原文未提供的并发症或处置。" + "rationale 不要列入与病例性别或部位冲突的鉴别诊断。" + "不要扩展到原文未提供的具体操作,处置建议只写尽快外科评估或急诊外科评估。" + "腹股沟包块步骤只引用原文给出的部位、大小和压痛等信息,不写原文未给出体征;X线阶梯状液气平已支持肠梗阻,不要写排除肠梗阻。" + "final_answer 必须字面包含外科评估、急诊外科评估或手术评估之一,不得建议观察、延迟外科评估或延迟手术。" + ) + elif task_type == "Preference": + groin_repair_rules = ( + "腹股沟包块合并阶梯状液气平时,chosen 必须写嵌顿性腹股沟疝合并肠梗阻并建议尽快外科评估。" + "腹股沟包块合并阶梯状液气平的 Preference 修复中,chosen 必须字面包含:嵌顿性腹股沟疝合并肠梗阻;rejected 不得是疾病名,只能写同一病例下的低质量处置。" + "腹股沟包块合并阶梯状液气平时,所有字段禁止出现穿孔、引流、推挤、减压等原文未给出的并发症或处置。" + ) + task_specific_repair_rules = ( + "CoT 的 rationale 必须写成单个编号字符串,不得使用数组;必须包含六个以上有内容的编号步骤;final_answer 必须存在且可包含必要处置。" + if task_type == "CoT" + else ( + "Preference 的 rejected 必须是同一病例下的低质量回答,不得用与病例性别或部位冲突的其他疾病凑数。" + "如果 Preference 候选 rejected 是离题疾病或其他诊断名称,必须改写为同病例低质量处置建议,例如仅建议观察、延误外科评估、忽视关键检查或遗漏高危证据。" + "如果 Preference 候选 chosen 是离题疾病或其他错误诊断,必须改写为原始输入支持的正确答案。" + ) + ) + if task_type == "QA" and self._is_diagnostic_generation_source(source_text): + task_specific_repair_rules = ( + "QA 必须围绕原始病例的诊疗、处理、建议、分析或管理生成," + "不得退化为年龄、性别等人口学抽取题。" ) messages = [ { @@ -860,10 +1774,8 @@ def _render_repair_prompt( f"你是严格的 JSON 修复器。只输出一个合法 JSON 对象,字段固定为 {fields}。" "不要输出解释、markdown 或 。" "只能基于原始输入和候选输出修复结构,不得编造原文不存在的诊断、症状或检查。" - "CoT 的 rationale 必须写成单个编号字符串,不得使用数组;必须包含六个编号:1. 2. 3. 4. 5. 6.;final_answer 必须存在且简短。" - "Preference 的 rejected 必须是同一病例下的低质量回答,不得用与病例性别或部位冲突的其他疾病凑数。" - "如果 Preference 候选 rejected 是离题疾病或其他诊断名称,必须改写为同病例低质量处置建议,例如仅建议观察、延误外科评估、忽视关键检查或遗漏高危证据。" - "如果 Preference 候选 chosen 是离题疾病或其他错误诊断,必须改写为原始输入支持的正确答案。" + f"{stroke_repair_rules}" + f"{task_specific_repair_rules}" f"{groin_repair_rules}" "CoT 的 final_answer 必须是安全处置建议,不得输出明显错误的首要处理。" f"{guardrail}" @@ -873,9 +1785,11 @@ def _render_repair_prompt( "role": "user", "content": ( f"原始输入:{source_text}\n" - f"候选输出:{clipped}\n" - f"{note}\n" - "请修复为目标 JSON。" + + ( + "候选输出结构不合格,已丢弃。请只基于原始输入重新生成目标 JSON。" + if task_type == "CoT" + else f"候选输出:{clipped}\n{note}\n请修复为目标 JSON。" + ) ), }, ] @@ -916,14 +1830,50 @@ def _render_second_repair_prompt(self, task_type: str, source_text: str, raw_out fields = "/".join(self.required_fields.get(task_type, [])) guardrail = self._build_source_guardrail(source_text, task_type) source = source_text or "" + if task_type == "QA" and self._is_groin_obstruction_source(source): + return self._render_native_chat_template( + self._render_groin_qa_messages(source, repair_mode=True), + enable_thinking=False, + ) + if task_type == "CoT" and self._is_groin_obstruction_source(source): + return self._render_native_chat_template( + self._render_groin_cot_messages(source, repair_mode=True), + enable_thinking=False, + ) + self._cot_prefill_json_prefix(source) + if self._is_acute_stroke_source(source): + stroke_instruction = ( + "急性脑卒中样例二次修复时,必须完全重写。" + "不得沿用上一轮中的 MRI、SPECT、意识障碍、血糖升高、脑干梗死、血管痉挛或其他原文未给出的内容。" + "QA 只保留急性缺血性卒中判断与卒中中心/溶栓/取栓/血压血糖管理。" + "CoT 必须写出六个编号步骤,并把 final_answer 收束到卒中中心评估、溶栓和必要时取栓评估。" + ) + else: + stroke_instruction = "" groin_instruction = "" if "腹股沟" in source and "阶梯状液气平" in source: - groin_instruction = "腹股沟包块合并阶梯状液气平时,诊断和处置只写:嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。" + groin_instruction = ( + "腹股沟包块合并阶梯状液气平时,诊断和处置只写:嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估,不写其他诊断。" + "rationale 需要写出病史、腹股沟包块、X线液气平、诊断推断、风险判断和处置建议,不要写空编号。" + "rationale 不要列入与病例性别或部位冲突的鉴别诊断,final_answer 必须字面包含外科评估、急诊外科评估或手术评估之一。" + "不要扩展到原文未提供的具体操作,处置建议只写尽快外科评估或急诊外科评估。" + "腹股沟包块步骤只引用原文给出的部位、大小和压痛等信息,不写原文未给出体征;X线阶梯状液气平已支持肠梗阻,不要写排除肠梗阻。" + ) + task_specific_repair_rules = ( + "CoT 的 rationale 必须写成单个编号字符串,不得使用数组;必须包含六个以上有实质内容的编号步骤;每步应引用原始输入或医学判断。" + if task_type == "CoT" + else "Preference 的 rejected 必须是同一病例下的低质量回答,不得用无关疾病凑数。" + ) + if task_type == "QA" and self._is_diagnostic_generation_source(source): + task_specific_repair_rules = ( + "QA 必须围绕原始病例的诊疗、处理、建议、分析或管理生成," + "不得退化为年龄、性别等人口学抽取题。" + ) content = ( f"你是严格的 JSON 二次修复器。只输出一个合法 JSON 对象,字段固定为 {fields}。" "请完全重写,不要沿用上一轮原句,不要输出解释、markdown 或 。" "必须只根据原始输入和允许的医学结论生成,不能扩展原文未给出的并发症或处置。" - "CoT 的 rationale 必须写成单个编号字符串,不得使用数组;必须包含六个编号:1. 2. 3. 4. 5. 6.;final_answer 必须存在。" + f"{stroke_instruction}" + f"{task_specific_repair_rules}" f"{groin_instruction}" f"{guardrail}" ) @@ -945,10 +1895,20 @@ def _render_second_repair_prompt(self, task_type: str, source_text: str, raw_out return self._render_native_chat_template(messages, enable_thinking=False) return self._render_repair_prompt(task_type, source_text, sanitized, self._build_repair_retry_note(task_type, source_text, sanitized)) - def _normalize_parsed_data(self, task_type: str, data: Any) -> Optional[Dict[str, Any]]: + def _normalize_parsed_data( + self, + task_type: str, + data: Any, + source_text: Optional[str] = None, + ) -> Optional[Dict[str, Any]]: if not isinstance(data, dict): return None + if task_type == "QA": + data = self._extract_qa_candidate_payload(data, source_text) + if not isinstance(data, dict): + return None + allowed = self.required_fields.get(task_type, []) if task_type == "QA" and "answer" not in data: for alias in ["处理原则", "诊断", "结论", "回答", "answer_text"]: @@ -964,17 +1924,142 @@ def _normalize_parsed_data(self, task_type: str, data: Any) -> Optional[Dict[str for i, step in enumerate(normalized["rationale"]) if str(step).strip() ) - elif task_type == "CoT" and isinstance(normalized.get("rationale"), str): - normalized["rationale"] = self._normalize_cot_rationale_text(normalized["rationale"]) + if task_type == "CoT": + normalized["question"] = self._clean_cot_field_text( + normalized.get("question"), + soften_direct_medication=False, + ) + normalized["rationale"] = self._normalize_cot_rationale_text( + self._clean_cot_field_text(normalized.get("rationale")) + ) + normalized["final_answer"] = self._clean_cot_field_text(normalized.get("final_answer")) + for key in ("question", "rationale", "final_answer"): + normalized[key] = self._clean_source_specific_medical_text( + normalized.get(key, ""), + source_text, + ) + if self._is_acute_stroke_source(source_text or ""): + for key in ("question", "rationale", "final_answer"): + normalized[key] = self._sanitize_acute_stroke_generated_text( + normalized.get(key, "") + ) + normalized["rationale"] = self._renumber_cot_steps(normalized.get("rationale", "")) + elif task_type == "QA": + normalized["question"] = self._clean_medical_answer_text( + normalized.get("question"), + soften_direct_medication=False, + ) + normalized["answer"] = self._clean_medical_answer_text(normalized.get("answer")) + for key in ("question", "answer"): + normalized[key] = self._clean_source_specific_medical_text( + normalized.get(key, ""), + source_text, + ) + if self._is_acute_stroke_source(source_text or ""): + for key in ("question", "answer"): + normalized[key] = self._sanitize_acute_stroke_generated_text( + normalized.get(key, "") + ) + normalized = self._truncate_fields("QA", normalized) + elif task_type == "Preference": + normalized["question"] = self._clean_medical_answer_text( + normalized.get("question"), + soften_direct_medication=False, + ) + for key in ("chosen", "rejected"): + normalized[key] = self._normalize_embedded_preference_text(normalized.get(key)) + normalized["preference_reason"] = self._clean_medical_answer_text( + normalized.get("preference_reason") + ) + for key in ("question", "chosen", "rejected", "preference_reason"): + normalized[key] = self._clean_source_specific_medical_text( + normalized.get(key, ""), + source_text, + ) + if self._is_acute_stroke_source(source_text or ""): + for key in ("question", "chosen", "rejected", "preference_reason"): + normalized[key] = self._sanitize_acute_stroke_generated_text( + normalized.get(key, "") + ) return normalized + def _extract_qa_candidate_payload( + self, + data: Dict[str, Any], + source_text: Optional[str] = None, + ) -> Dict[str, Any]: + source = source_text or "" + + zh_question_alias = "问题" + zh_answer_alias = "回答" + + def default_question() -> str: + if self._is_acute_stroke_source(source): + return "是否符合急性缺血性卒中评估条件?" + if self._is_groin_obstruction_source(source): + return "最可能的处理重点是什么?" + if "发热" in source and "儿童" in source: + return "最可能的处理重点是什么?" + return "最可能的处理重点是什么?" + + def from_answer_text(answer_text: Any, question_text: Any = None) -> Optional[Dict[str, Any]]: + answer = str(answer_text or "").strip() + if not answer: + return None + question = str(question_text or "").strip() or default_question() + return {"question": question, "answer": answer} + + if self._is_acute_stroke_source(source): + raw_answer_text = str(data.get("answer") or "") + primary = from_answer_text(data.get("answer"), data.get("question")) + if primary is not None and any(term in raw_answer_text for term in ["卒中中心", "溶栓", "取栓", "再灌注"]): + compact_answer = "考虑急性缺血性卒中,应立即启动卒中中心评估,尽快评估溶栓或取栓,并监测血压和血糖。" + return {"question": default_question(), "answer": compact_answer} + candidate = from_answer_text(data.get("QA"), data.get("question")) + if candidate is not None and any(term in candidate["answer"] for term in ["卒中中心", "溶栓", "取栓", "再灌注"]): + return candidate + if primary is not None: + compact_answer = "考虑急性缺血性卒中,应立即启动卒中中心评估,尽快评估溶栓或取栓,并监测血压和血糖。" + return {"question": default_question(), "answer": compact_answer} + if candidate is not None: + return candidate + + for key in ("qa", "QA"): + value = data.get(key) + if isinstance(value, dict): + candidate = from_answer_text(value.get("answer") or value.get(zh_answer_alias), value.get("question") or value.get(zh_question_alias)) + if candidate is not None: + return candidate + elif isinstance(value, str): + candidate = from_answer_text(value) + if candidate is not None: + return candidate + + if "question" in data and isinstance(data.get("answer"), str): + candidate = from_answer_text(data.get("answer"), data.get("question")) + if candidate is not None: + return candidate + + if "question" in data and isinstance(data.get("QA"), str): + candidate = from_answer_text(data.get("QA"), data.get("question")) + if candidate is not None: + return candidate + + for alias in ("回答", "结论", "诊断", "处理原则", "answer_text"): + if alias in data: + candidate = from_answer_text(data.get(alias), data.get("question") or data.get(zh_question_alias)) + if candidate is not None: + return candidate + + return data + def _normalize_cot_rationale_text(self, rationale: str) -> str: text = re.sub(r"\s+", " ", rationale or "").strip() if not text: return text if len(re.findall(r"(\d+[\.、]|步骤\d+|->)", text)) >= 3: - return text + return self._renumber_cot_steps(text) parts = [p.strip(" ;;。") for p in re.split(r"[。;;]", text) if p.strip(" ;;。")] if len(parts) < 3: @@ -988,6 +2073,23 @@ def _normalize_cot_rationale_text(self, rationale: str) -> str: steps = parts[:6] return "".join(f"{i + 1}. {step}。" for i, step in enumerate(steps)) + def _renumber_cot_steps(self, text: str) -> str: + value = re.sub(r"\s+", " ", text or "").strip() + matches = list(re.finditer(r"(? SamplingParams: if task_type == "QA": return SamplingParams( temperature=0.0, - top_p=0.8, - max_tokens=220, + top_p=0.7, + max_tokens=160, stop=["<|im_end|>"], repetition_penalty=1.0, + structured_outputs=self._structured_json_params("QA"), ) if task_type == "Preference": return SamplingParams( temperature=0.0, top_p=1.0, - max_tokens=320, + max_tokens=900, stop=["<|im_end|>"], repetition_penalty=1.03, structured_outputs=self._structured_json_params("Preference"), @@ -1032,7 +2135,7 @@ def _build_sampling_params(self, task_type: str) -> SamplingParams: return SamplingParams( temperature=0.0, top_p=1.0, - max_tokens=900, + max_tokens=1800, stop=["<|im_end|>"], repetition_penalty=1.05, structured_outputs=self._structured_json_params("CoT"), @@ -1041,11 +2144,11 @@ def _build_sampling_params(self, task_type: str) -> SamplingParams: def _build_repair_sampling_params(self, task_type: str) -> SamplingParams: # 修复阶段使用更低随机性,优先稳定产出结构化 JSON if task_type == "QA": - max_tokens = 220 + max_tokens = 700 elif task_type == "CoT": - max_tokens = 1400 + max_tokens = 2200 else: - max_tokens = 360 + max_tokens = 900 return SamplingParams( temperature=0.0, @@ -1053,7 +2156,24 @@ def _build_repair_sampling_params(self, task_type: str) -> SamplingParams: max_tokens=max_tokens, stop=["<|im_end|>"], repetition_penalty=1.0, - structured_outputs=self._structured_json_params(task_type) if task_type in ["CoT", "Preference"] else None, + structured_outputs=self._structured_json_params(task_type) if task_type in ["QA", "CoT", "Preference"] else None, + ) + + def _build_review_sampling_params(self, task_type: str, attempt_no: int) -> SamplingParams: + if task_type == "QA": + max_tokens = 700 + elif task_type == "CoT": + max_tokens = 3200 + else: + max_tokens = 1400 + + return SamplingParams( + temperature=0.0 if attempt_no <= 2 else 0.2, + top_p=0.9, + max_tokens=max_tokens, + stop=["<|im_end|>"], + repetition_penalty=1.02, + structured_outputs=self._structured_json_params(task_type) if task_type in ["QA", "CoT", "Preference"] else None, ) def _structured_json_params(self, task_type: str) -> Any: @@ -1063,6 +2183,16 @@ def _structured_json_params(self, task_type: str) -> Any: return {"json": schema, "disable_any_whitespace": True} def _json_schema_for_task(self, task_type: str) -> Dict[str, Any]: + if task_type == "QA": + return { + "type": "object", + "additionalProperties": False, + "required": ["question", "answer"], + "properties": { + "question": {"type": "string", "minLength": 4, "maxLength": 220}, + "answer": {"type": "string", "minLength": 8, "maxLength": 220}, + }, + } if task_type == "CoT": return { "type": "object", @@ -1073,9 +2203,9 @@ def _json_schema_for_task(self, task_type: str) -> Dict[str, Any]: "rationale": { "type": "string", "minLength": 40, - "maxLength": 900, + "maxLength": 2200, }, - "final_answer": {"type": "string", "minLength": 8, "maxLength": 220}, + "final_answer": {"type": "string", "minLength": 8, "maxLength": 420}, }, } if task_type == "Preference": @@ -1085,9 +2215,9 @@ def _json_schema_for_task(self, task_type: str) -> Dict[str, Any]: "required": ["question", "chosen", "rejected", "preference_reason"], "properties": { "question": {"type": "string", "minLength": 4, "maxLength": 220}, - "chosen": {"type": "string", "minLength": 8, "maxLength": 180}, - "rejected": {"type": "string", "minLength": 8, "maxLength": 180}, - "preference_reason": {"type": "string", "minLength": 12, "maxLength": 220}, + "chosen": {"type": "string", "minLength": 8, "maxLength": 1200}, + "rejected": {"type": "string", "minLength": 8, "maxLength": 1200}, + "preference_reason": {"type": "string", "minLength": 12, "maxLength": 1200}, }, } raise ValueError(f"不支持的 task_type: {task_type}") @@ -1116,17 +2246,49 @@ def _truncate_text_at_boundary(self, text: str, limit: int) -> str: return cut.rstrip() def _truncate_qa_fields(self, data: Dict[str, Any]) -> Dict[str, Any]: + return self._truncate_fields("QA", data) + + def _truncate_fields(self, task_type: str, data: Dict[str, Any]) -> Dict[str, Any]: normalized = dict(data) - question = str(normalized.get("question", "")).strip() - answer = str(normalized.get("answer", "")).strip() + for field, limit in self.length_limits.get(task_type, {}).items(): + normalized[field] = self._truncate_text_at_boundary( + str(normalized.get(field, "")).strip(), + limit, + ) - q_limit = self.length_limits["QA"]["question"] - a_limit = self.length_limits["QA"]["answer"] + return normalized - normalized["question"] = self._truncate_text_at_boundary(question, q_limit) - normalized["answer"] = self._truncate_text_at_boundary(answer, a_limit) + def _fallback_plain_text_qa( + self, + text: str, + source_text: Optional[str] = None, + ) -> Optional[Dict[str, Any]]: + candidate = self._strip_generation_scaffolding( + self._strip_reasoning_text(text or "") + ).strip() + if not candidate: + return None + if candidate.startswith(("{", "[")) and candidate.endswith(("}", "]")): + return None + if len(candidate) < 8: + return None + lowered = candidate.lower() + if "json" in lowered or re.search(r"不是\s*json|输出\s*json|json\s*格式", candidate, flags=re.IGNORECASE): + return None + if self._looks_like_meta_or_thought(candidate) or self._looks_like_model_monologue(candidate): + return None - return normalized + payload = { + "question": self._suggest_qa_question(source_text or ""), + "answer": candidate, + } + normalized = self._normalize_parsed_data("QA", payload, source_text) + if normalized is None: + return None + normalized = self._truncate_fields("QA", normalized) + if self._validate_generated_data("QA", normalized, source_text): + return normalized + return None def _try_parse_and_validate( self, @@ -1135,27 +2297,141 @@ def _try_parse_and_validate( source_text: Optional[str] = None, ) -> Optional[Dict[str, Any]]: clean_text = self._clean_json_string(text) + detached_qa = self._extract_detached_nested_object(text, "qa") if task_type == "QA" else None candidates = [ clean_text, self._repair_json_syntax_only(clean_text), + self._escape_unquoted_inner_value_quotes(self._repair_json_syntax_only(clean_text)), + self._salvage_truncated_json_object(clean_text), clean_text.replace('\n', '\\n'), self._repair_json_syntax_only(clean_text).replace('\n', '\\n'), + self._escape_unquoted_inner_value_quotes(self._repair_json_syntax_only(clean_text)).replace('\n', '\\n'), ] for candidate in candidates: + if not candidate: + continue try: data = json.loads(candidate, strict=False) - data = self._normalize_parsed_data(task_type, data) + if task_type == "QA" and isinstance(data, dict) and detached_qa and "qa" not in data: + merged = dict(data) + merged["qa"] = detached_qa + data = merged + data = self._normalize_parsed_data(task_type, data, source_text) if data is None: continue - if task_type == "QA": - data = self._truncate_qa_fields(data) + if task_type in {"QA", "CoT"}: + data = self._truncate_fields(task_type, data) if self._validate_generated_data(task_type, data, source_text): return data except Exception: continue + if task_type == "QA": + for fallback_text in (clean_text, text): + parsed = self._fallback_plain_text_qa(fallback_text, source_text) + if parsed is not None: + return parsed return None + def _render_review_regeneration_prompt( + self, + task_type: str, + source_text: str, + failed_outputs: List[str], + attempt_no: int, + ) -> str: + fields = self.required_fields.get(task_type, []) + field_list = ", ".join(fields) + guardrail = self._build_source_guardrail(source_text, task_type) + clipped_failures = "\n\n".join( + f"[invalid_output_{i + 1}]\n{str(text or '')[:1200]}" + for i, text in enumerate(failed_outputs[-4:]) + if str(text or "").strip() + ) + task_rules = { + "QA": ( + "Output exactly one JSON object with question and answer. " + "The answer must be a complete Chinese medical answer grounded in the source." + ), + "CoT": ( + "Output exactly one JSON object with question, rationale and final_answer. " + "rationale must be one Chinese string, not an array. " + "rationale must contain at least six numbered, substantive steps: 1. 2. 3. 4. 5. 6. " + "final_answer must be present and must summarize a safe conclusion or next-step recommendation." + ), + "Preference": ( + "Output exactly one JSON object with question, chosen, rejected and preference_reason. " + "chosen must be the higher-quality grounded answer; rejected must be a lower-quality answer for the same case; " + "preference_reason must compare why chosen is better." + ), + }.get(task_type, "") + content = ( + "你是严格的数据合成复审器。前几次模型输出没有通过质量校验。" + "必须完全丢弃失败输出,只基于原始输入重新生成合格数据。" + "只输出一个合法 JSON 对象,不输出解释、Markdown、。" + "禁止输出 status、reason、raw_output、failed、repair_failed 等状态字段。" + f"固定字段为: {field_list}。" + f"{task_rules}" + f"{guardrail}" + f"这是第 {attempt_no} 次复审重生成,必须一次性满足字段、JSON 和医学质量要求。" + ) + user_content = ( + f"原始输入:\n{source_text}\n\n" + f"已判定失败的输出,仅作为反例,禁止沿用:\n{clipped_failures}\n\n" + f"请重新生成 {task_type} JSON。" + ) + messages = [ + {"role": "system", "content": content}, + {"role": "user", "content": user_content}, + ] + if self._qa_uses_native_template: + prompt = self._render_native_chat_template(messages, enable_thinking=False) + else: + prompt = content + "\n\n" + user_content + if task_type == "CoT" and self._is_groin_obstruction_source(source_text): + prompt += self._cot_prefill_json_prefix(source_text) + return prompt + + def _review_regenerate_failed_item( + self, + task_type: str, + item: Dict[str, Any], + failed_outputs: List[str], + ) -> Dict[str, Any]: + max_attempts = 8 if task_type in {"CoT", "Preference"} else 4 + source_text = item.get("source_text", "") + observed_failures = [ + self._sanitize_failed_repair_output(source_text, text) + for text in failed_outputs + if str(text or "").strip() + ] + + for attempt_no in range(1, max_attempts + 1): + prompt = self._render_review_regeneration_prompt( + task_type, + source_text, + observed_failures, + attempt_no, + ) + outputs = self.llm.generate([prompt], self._build_review_sampling_params(task_type, attempt_no)) + regenerated_text = outputs[0].outputs[0].text if outputs and outputs[0].outputs else "" + candidate_text = self._apply_prefill_json_prefix(task_type, regenerated_text, source_text) + parsed = self._try_parse_and_validate(task_type, candidate_text, source_text) + if parsed is not None: + return { + "status": "success", + "data": parsed, + "repaired": True, + "repair_attempts": 2 + attempt_no, + "review_regenerated": True, + } + observed_failures.append(self._sanitize_failed_repair_output(source_text, candidate_text)) + + idx = item.get("idx", "?") + raise RuntimeError( + f"{task_type} generation for item {idx} failed quality validation after review regeneration" + ) + def _repair_failed_batch(self, task_type: str, repair_items: List[Dict[str, Any]]) -> Dict[int, Dict[str, Any]]: """ 对首轮失败样本执行二阶段修复。 @@ -1176,7 +2452,8 @@ def _repair_failed_batch(self, task_type: str, repair_items: List[Dict[str, Any] for item, output in zip(repair_items, repair_outputs): idx = item["idx"] repaired_text = output.outputs[0].text if output.outputs else "" - parsed = self._try_parse_and_validate(task_type, repaired_text, item["source_text"]) + repaired_candidate = self._apply_prefill_json_prefix(task_type, repaired_text, item["source_text"]) + parsed = self._try_parse_and_validate(task_type, repaired_candidate, item["source_text"]) if parsed is not None: repaired_result_map[idx] = { "status": "success", @@ -1189,7 +2466,7 @@ def _repair_failed_batch(self, task_type: str, repair_items: List[Dict[str, Any] "idx": idx, "source_text": item["source_text"], "raw_output": item.get("raw_output", ""), - "repair_raw_output": repaired_text, + "repair_raw_output": repaired_candidate, }) if retry_items: @@ -1202,7 +2479,8 @@ def _repair_failed_batch(self, task_type: str, repair_items: List[Dict[str, Any] for item, output in zip(retry_items, retry_outputs): idx = item["idx"] retry_text = output.outputs[0].text if output.outputs else "" - parsed = self._try_parse_and_validate(task_type, retry_text, item["source_text"]) + retry_candidate = self._apply_prefill_json_prefix(task_type, retry_text, item["source_text"]) + parsed = self._try_parse_and_validate(task_type, retry_candidate, item["source_text"]) if parsed is not None: repaired_result_map[idx] = { "status": "success", @@ -1212,24 +2490,28 @@ def _repair_failed_batch(self, task_type: str, repair_items: List[Dict[str, Any] } continue - repaired_result_map[idx] = { - "status": "failed", - "reason": "repair_failed", - "raw_output": item.get("raw_output", ""), - "repair_raw_output": item.get("repair_raw_output", ""), - "second_repair_raw_output": retry_text, - } + repaired_result_map[idx] = self._review_regenerate_failed_item( + task_type, + item, + [ + item.get("raw_output", ""), + item.get("repair_raw_output", ""), + retry_candidate, + ], + ) for item in retry_items: idx = item["idx"] if idx in repaired_result_map: continue - repaired_result_map[idx] = { - "status": "failed", - "reason": "repair_failed", - "raw_output": item.get("raw_output", ""), - "repair_raw_output": item.get("repair_raw_output", ""), - } + repaired_result_map[idx] = self._review_regenerate_failed_item( + task_type, + item, + [ + item.get("raw_output", ""), + item.get("repair_raw_output", ""), + ], + ) return repaired_result_map @@ -1251,7 +2533,8 @@ def generate_data_batch(self, task_type: str, inputs: List[str]) -> List[Dict[st for i, output in enumerate(outputs): generated_text = output.outputs[0].text if output.outputs else "" - parsed = self._try_parse_and_validate(task_type, generated_text, inputs[i]) + candidate_text = self._apply_prefill_json_prefix(task_type, generated_text, inputs[i]) + parsed = self._try_parse_and_validate(task_type, candidate_text, inputs[i]) if parsed is not None: results[i] = {"status": "success", "data": parsed} continue @@ -1260,7 +2543,7 @@ def generate_data_batch(self, task_type: str, inputs: List[str]) -> List[Dict[st repair_items.append({ "idx": i, "source_text": inputs[i], - "raw_output": generated_text, + "raw_output": candidate_text, }) repaired_map = self._repair_failed_batch(task_type, repair_items) @@ -1269,20 +2552,12 @@ def generate_data_batch(self, task_type: str, inputs: List[str]) -> List[Dict[st if idx in repaired_map: results[idx] = repaired_map[idx] else: - results[idx] = { - "status": "failed", - "reason": "repair_missing", - "raw_output": item.get("raw_output", ""), - } + raise RuntimeError(f"{task_type} repair result missing for item {idx}") # 理论上不应存在 None,这里兜底 for i, r in enumerate(results): if r is None: - results[i] = { - "status": "failed", - "reason": "internal_empty_result", - "raw_output": "", - } + raise RuntimeError(f"{task_type} internal empty result for item {i}") return [r for r in results if r is not None] diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/final_delivery_part1.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/final_delivery_part1.py index 25642fd1..4d515d40 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/final_delivery_part1.py +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/final_delivery_part1.py @@ -18,13 +18,13 @@ def resolve_model_path() -> str: candidates = [ os.getenv("MODEL_PATH"), os.getenv("DATA_SYNTHESIS_MODEL_PATH"), - "/model/Qwen/Qwen3-1___7b-Medical-R1-sft", - str(Path.home() / ".cache/modelscope/testUser/Qwen3-1___7b-Medical-R1-sft"), + "/model/Qwen/Qwen3-4B-Instruct-2507", + str(Path.home() / ".cache/modelscope/testUser/Qwen3-4B-Instruct-2507"), ] for path in candidates: if path and os.path.exists(path): return path - return os.getenv("MODEL_PATH") or "/model/Qwen/Qwen3-1___7b-Medical-R1-sft" + return os.getenv("MODEL_PATH") or "/model/Qwen/Qwen3-4B-Instruct-2507" MODEL_PATH = resolve_model_path() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/prepare_golden_data.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/prepare_golden_data.py index a63bb49b..a8590e23 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/prepare_golden_data.py +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/prepare_golden_data.py @@ -194,9 +194,9 @@ def create_golden_dataset(): print(f"✅ 金标准数据集已生成: {OUTPUT_FILE}") print(f"📊 包含样本数: {len(dataset)} 条") print("="*50) - print("👉 下一步:请运行 data_evaluator.py,让模型对这些数据打分,") + print("下一步:请使用独立的 data_quality_evaluator_service 对这些数据打分,") print(" 然后计算 模型分 与 这里预置的 human_scores 的一致性。") print(" (你也可以手动打开 json 修改 human_scores 以符合你的个人标准)") if __name__ == "__main__": - create_golden_dataset() \ No newline at end of file + create_golden_dataset() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/run_50_each_test.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/run_50_each_test.py index 4f367a1b..bd591bec 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/run_50_each_test.py +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/run_50_each_test.py @@ -22,8 +22,8 @@ def resolve_model_path() -> str: candidates = [ os.getenv("MODEL_PATH"), os.getenv("DATA_SYNTHESIS_MODEL_PATH"), - "/model/Qwen/Qwen3-1___7b-Medical-R1-sft", - str(Path.home() / ".cache/modelscope/testUser/Qwen3-1___7b-Medical-R1-sft"), + "/model/Qwen/Qwen3-4B-Instruct-2507", + str(Path.home() / ".cache/modelscope/testUser/Qwen3-4B-Instruct-2507"), ] for path in candidates: if path and os.path.exists(path): diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_acute_stroke_preference_regression.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_acute_stroke_preference_regression.py new file mode 100644 index 00000000..42cea31d --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_acute_stroke_preference_regression.py @@ -0,0 +1,37 @@ +import unittest + +from data_synthesizer import MedicalDataSynthesizer + + +class AcuteStrokePreferenceRegressionTests(unittest.TestCase): + def test_accepts_rejected_answer_that_omits_reperfusion_as_low_quality(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = ( + "测试编号:DS-13\n" + "病例摘要:男,72岁,突发言语不清和右侧肢体无力2小时," + "高血压病史,头颅CT未见出血。请生成急性脑卒中评估相关数据。" + ) + parsed = { + "question": "该患者急诊卒中处理应如何判断?", + "chosen": ( + "患者符合急性缺血性卒中可能,应立即进入卒中中心流程," + "评估静脉溶栓时间窗和禁忌证,必要时评估机械取栓,并同步管理血压和血糖。" + ), + "rejected": ( + "仅建议回家观察或普通门诊随访,未及时进行卒中中心评估," + "遗漏溶栓时间窗、机械取栓和再灌注治疗评估。" + ), + "preference_reason": ( + "chosen 结合突发神经功能缺损和CT未见出血,及时覆盖溶栓、取栓及再灌注评估;" + "rejected 延误急性卒中处置并遗漏关键时间窗。" + ), + } + + normalized = synth._normalize_parsed_data("Preference", parsed, source) + + self.assertIsNotNone(normalized) + self.assertTrue(synth._validate_generated_data("Preference", normalized, source)) + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_generation_quality_regressions.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_generation_quality_regressions.py new file mode 100644 index 00000000..815b6744 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_generation_quality_regressions.py @@ -0,0 +1,61 @@ +import unittest + +from data_synthesizer import MedicalDataSynthesizer + + +class GenerationQualityRegressionTests(unittest.TestCase): + def test_qa_demographic_extraction_is_invalid_for_diagnostic_source(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = ( + "测试编号:DS-10\n" + "数据来源风格:中文临床病例公开样式\n\n" + "病例摘要:女,45岁,反复上腹痛半年,餐后加重,胃镜提示胃窦溃疡,幽门螺杆菌阳性。" + "请生成诊疗思路相关的合成数据。" + ) + parsed = { + "question": "患者性别如何?", + "answer": "该患者性别为女性。", + } + + normalized = synth._normalize_parsed_data("QA", parsed, source) + + self.assertIsNotNone(normalized) + self.assertFalse(synth._validate_generated_data("QA", normalized, source)) + + def test_preference_stringified_payload_is_normalized_to_plain_text(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = ( + "患者咨询:孕24周,最近出现轻度贫血,血红蛋白102g/L,担心补铁影响胎儿。" + "请围绕孕期贫血科普生成中文QA、CoT和Preference。" + ) + parsed = { + "question": "孕24周,最近出现轻度贫血,血红蛋白102g/L,担心补铁影响胎儿。", + "chosen": ( + "{'QA': '孕期贫血是否需要补铁?', " + "'CoT': '孕期贫血是指孕妇血红蛋白水平低于正常范围,可能导致胎儿生长受限、早产等风险。', " + "'Preference': '孕期贫血确实需要关注,但轻度贫血通过合理补铁是可以控制的。'}" + ), + "rejected": ( + "{'QA': '孕期贫血是否会导致胎儿畸形?', " + "'CoT': '孕期贫血可能会导致胎儿生长受限、早产等问题,但不会直接导致胎儿畸形。', " + "'Preference': '此问题偏离了贫血的直接处理,且贫血与胎儿畸形无直接因果关系。'}" + ), + "preference_reason": "chosen 更贴近患者问题,rejected 偏离了贫血的直接处理。", + } + + normalized = synth._normalize_parsed_data("Preference", parsed, source) + + self.assertIsNotNone(normalized) + self.assertEqual( + normalized["chosen"], + "孕期贫血确实需要关注,但轻度贫血通过合理补铁是可以控制的。", + ) + self.assertEqual( + normalized["rejected"], + "此问题偏离了贫血的直接处理,且贫血与胎儿畸形无直接因果关系。", + ) + self.assertTrue(synth._validate_generated_data("Preference", normalized, source)) + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_medication_safety_cleanup.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_medication_safety_cleanup.py new file mode 100644 index 00000000..516a5c6f --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_medication_safety_cleanup.py @@ -0,0 +1,320 @@ +import json +import unittest + +from data_synthesizer import MedicalDataSynthesizer + + +class MedicationSafetyCleanupTests(unittest.TestCase): + def test_softened_medication_advice_does_not_keep_modal_prefix(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = ( + "患者咨询文本:我今年 56 岁,已有多年高血压病史,平时服用氨氯地平控制血压。" + "最近一周出现轻度踝部水肿,血压大多在 145/92 mmHg 左右。" + "请问这种情况是否需要调整用药?日常应该如何监测血压和生活方式管理?" + ) + raw = json.dumps( + { + "question": source, + "answer": "如果确诊为高血压,医生可能会调整用药方案。请不要自行调整药物。", + }, + ensure_ascii=False, + ) + + parsed = synth._try_parse_and_validate("QA", raw, source) + + self.assertIsNotNone(parsed) + answer = parsed["answer"] + self.assertIn("应由医生评估是否调整用药方案", answer) + self.assertNotIn("医生可能会应由医生评估", answer) + self.assertNotIn("方案方案", answer) + self.assertIn("不要自行调整药物", answer) + + def test_softened_medication_advice_does_not_duplicate_whether_phrase(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = ( + "患者56岁,高血压多年,服用氨氯地平控制血压。" + "最近一周出现轻度踝部水肿,血压145/92mmHg左右,询问是否需要调整用药。" + ) + raw = json.dumps( + { + "question": source, + "answer": ( + "这种情况需要结合其他因素来判断是否需要调整用药。" + "具体是否需要调整用药,还要看血压记录和水肿变化。" + ), + }, + ensure_ascii=False, + ) + + parsed = synth._try_parse_and_validate("QA", raw, source) + + self.assertIsNotNone(parsed) + answer = parsed["answer"] + self.assertNotIn("是否应由医生评估是否调整用药方案", answer) + self.assertNotIn("判断是否应由医生评估", answer) + self.assertIn("由医生评估", answer) + + def test_softened_medication_advice_removes_broken_connector_and_deduplicates(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + text = ( + "轻度踝部水肿可能与高血压有关,但需要结合其他因素来应由医生评估是否调整用药方案。" + "血压在145/92mmHg左右,具体应由医生评估是否调整用药方案,还需要考虑水肿变化。" + "请不要自行调整药物。" + ) + + cleaned = synth._clean_medical_answer_text(text) + + self.assertNotIn("来应由医生评估", cleaned) + self.assertEqual(cleaned.count("医生评估是否调整用药方案"), 1) + self.assertIn("需要结合其他因素,由医生评估是否调整用药方案", cleaned) + self.assertIn("不要自行调整药物", cleaned) + + def test_softened_medication_advice_deduplicates_equivalent_safe_phrases(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + text = ( + "需要结合其他因素,由医生评估是否调整用药方案。" + "具体应由医生评估是否调整用药方案,还需要考虑肾功能。" + ) + + cleaned = synth._clean_medical_answer_text(text) + + self.assertEqual(cleaned.count("医生评估是否调整用药方案"), 1) + self.assertIn("由医生进一步评估", cleaned) + + def test_cot_medication_advice_removes_possible_safe_phrase_prefix(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = ( + "患者56岁,有多年高血压病史,服用氨氯地平控制血压," + "最近一周出现轻度踝部水肿,血压多为145/92mmHg左右。" + ) + raw = json.dumps( + { + "question": "患者踝部水肿和血压偏高时是否需要调整用药?", + "rationale": ( + "1. 患者有高血压病史。" + "2. 服用氨氯地平后出现踝部水肿。" + "3. 血压145/92mmHg仍高于目标范围。" + "4. 水肿可能与药物不良反应有关。" + "5. 这种情况可能应由医生评估是否调整用药方案。" + "6. 需记录血压和水肿变化后复诊。" + ), + "final_answer": "轻度踝部水肿可能提示应由医生评估是否调整用药方案,并定期监测血压。", + }, + ensure_ascii=False, + ) + + parsed = synth._try_parse_and_validate("CoT", raw, source) + + self.assertIsNotNone(parsed) + combined = parsed["rationale"] + parsed["final_answer"] + self.assertNotIn("可能应由医生评估是否调整用药方案", combined) + self.assertNotIn("可能提示应由医生评估是否调整用药方案", combined) + self.assertIn("应由医生评估是否调整用药方案", combined) + + def test_hypertension_edema_preference_removes_hard_emergency_threshold(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = ( + "患者56岁,有多年高血压病史,服用氨氯地平控制血压," + "最近一周出现轻度踝部水肿,血压多为145/92mmHg左右。" + ) + raw = json.dumps( + { + "question": "患者踝部水肿和血压偏高时是否需要调整用药?", + "chosen": ( + "建议监测血压和水肿变化,保持低盐饮食。" + "如果水肿持续或加重,或者血压超过180/110mmHg,应由医生评估是否调整用药方案。" + ), + "rejected": "可以自行加大降压药剂量,先不用复诊。", + "preference_reason": "chosen强调监测和医生评估,rejected存在自行调整药物的安全风险。", + }, + ensure_ascii=False, + ) + + parsed = synth._try_parse_and_validate("Preference", raw, source) + + self.assertIsNotNone(parsed) + chosen = parsed["chosen"] + self.assertNotIn("180/110mmHg", chosen) + self.assertIn("血压持续高于目标范围", chosen) + self.assertIn("应由医生评估是否调整用药方案", chosen) + + def test_hypertension_edema_output_stays_grounded_without_specific_complication_path(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = ( + "患者咨询文本:我今年 56 岁,已有多年高血压病史,平时服用氨氯地平控制血压。" + "最近一周出现轻度踝部水肿,血压大多在 145/92 mmHg 左右。" + "请问这种情况是否需要调整用药?日常应该如何监测血压和生活方式管理?" + ) + raw = json.dumps( + { + "question": source, + "answer": ( + "具体由医生进一步评估,还需要考虑其他因素,比如是否有蛋白尿、肾功能不全等。" + "如果确诊为心脏问题,可能需要使用ACEI或ARB类药物。" + ), + }, + ensure_ascii=False, + ) + + parsed = synth._try_parse_and_validate("QA", raw, source) + + self.assertIsNotNone(parsed) + answer = parsed["answer"] + for bad in ["蛋白尿", "肾功能不全", "心脏问题", "ACEI", "ARB"]: + self.assertNotIn(bad, answer) + self.assertIn("血压记录", answer) + self.assertIn("水肿变化", answer) + + def test_hypertension_edema_cot_removes_overexpanded_heart_kidney_route(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = ( + "患者56岁,有多年高血压病史,服用氨氯地平控制血压," + "最近一周出现轻度踝部水肿,血压多为145/92mmHg左右。" + ) + raw = json.dumps( + { + "question": "患者踝部水肿和血压偏高时是否需要调整用药?", + "rationale": ( + "1. 患者有高血压病史。" + "2. 服用氨氯地平后出现踝部水肿。" + "3. 血压145/92mmHg仍高于目标范围。" + "4. 建议进行心脏功能和肾功能的评估。" + "5. 如果确诊为心脏问题,可能需要使用ACEI或ARB类药物。" + "6. 踝部水肿可能提示其他问题,如心脏或肾脏问题,需要进一步检查。" + "7. 同时记录血压和水肿变化,并观察是否有呼吸困难、水肿加重等。" + ), + "final_answer": "建议您建议结合血压记录和水肿变化复诊评估。", + }, + ensure_ascii=False, + ) + + parsed = synth._try_parse_and_validate("CoT", raw, source) + + self.assertIsNotNone(parsed) + combined = parsed["rationale"] + parsed["final_answer"] + for bad in ["心脏功能", "心脏问题", "肾功能", "肾脏问题", "ACEI", "ARB", "呼吸困难"]: + self.assertNotIn(bad, combined) + self.assertNotIn("建议您建议", combined) + self.assertNotIn("建议您尽快就医,建议", combined) + self.assertNotRegex(combined, r"\d+\.\s*\d+\.") + for step in ["1.", "2.", "3.", "4.", "5."]: + self.assertIn(step, parsed["rationale"]) + self.assertIn("血压记录", combined) + self.assertIn("水肿变化", combined) + + def test_hypertension_edema_cleanup_removes_broken_residual_fragments(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = ( + "患者56岁,有多年高血压病史,服用氨氯地平控制血压," + "最近一周出现轻度踝部水肿,血压多为145/92mmHg左右。" + ) + raw = json.dumps( + { + "question": "患者踝部水肿和血压偏高时是否需要调整用药?", + "rationale": ( + "1. 轻度踝部水肿可能与高血压有关。" + "2. 如果症状持续或加重,应及时就医,排除其他潜在疾病,如或。" + "3. 建议记录血压变化。" + ), + "final_answer": "轻度踝部水肿应由医生评估是否调整用药方案。建议记录血压和水肿变化,并由医生评估是否调整用药方案。", + }, + ensure_ascii=False, + ) + + parsed = synth._try_parse_and_validate("CoT", raw, source) + + self.assertIsNotNone(parsed) + combined = parsed["rationale"] + parsed["final_answer"] + self.assertNotIn("如或", combined) + self.assertLessEqual(combined.count("医生评估是否调整用药方案"), 1) + + def test_hypertension_edema_preference_reason_removes_broken_other_fragment(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = ( + "患者56岁,有多年高血压病史,服用氨氯地平控制血压," + "最近一周出现轻度踝部水肿,血压多为145/92mmHg左右。" + ) + raw = json.dumps( + { + "question": "患者踝部水肿和血压偏高时是否需要调整用药?", + "chosen": "建议记录血压和水肿变化,由医生评估是否调整用药方案。", + "rejected": "只建议继续观察或自行调整用药,未结合血压记录和水肿变化;请不要自行调整药物。", + "preference_reason": "chosen更贴近本病例;rejected更侧重于排除其他,可能对患者造成不必要的健康风险。", + }, + ensure_ascii=False, + ) + + parsed = synth._try_parse_and_validate("Preference", raw, source) + + self.assertIsNotNone(parsed) + self.assertNotIn("排除其他,", parsed["preference_reason"]) + self.assertIn("泛化风险提示", parsed["preference_reason"]) + + def test_hypertension_edema_cot_removes_platform_residual_kidney_route(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = ( + "患者56岁,有多年高血压病史,服用氨氯地平控制血压," + "最近一周出现轻度踝部水肿,血压多为145/92mmHg左右。" + ) + raw = json.dumps( + { + "question": "患者踝部水肿和血压偏高时是否需要调整用药?", + "rationale": ( + "1. 根据您的描述,轻度踝部水肿可能与高血压有关,但需要进一步评估。" + "2. 氨氯地平是常用的降压药,但需注意其副作用,如踝部水肿、心悸等。" + "如果这些症状出现,可能提示药物对某些患者不适用,或者存在其他并发症。" + "3. 肾功能检查对于评估药物代谢很重要,因为氨氯地平主要通过肾脏排泄。" + "如果肾功能受损,药物可能蓄积,增加副作用风险。" + "4. 建议定期监测血压,记录每日血压变化。" + "5. 如果症状持续或加重,应及时就医,排除其他潜在疾病,如或肾脏疾病。" + ), + "final_answer": "建议您进行肾功能检查,并定期监测血压。", + }, + ensure_ascii=False, + ) + + parsed = synth._try_parse_and_validate("CoT", raw, source) + + self.assertIsNotNone(parsed) + combined = parsed["rationale"] + parsed["final_answer"] + for bad in ["肾功能", "肾脏", "心悸", "并发症", "药物蓄积"]: + self.assertNotIn(bad, combined) + self.assertIn("血压记录", combined) + self.assertIn("水肿变化", combined) + + def test_hypertension_edema_preference_rejected_uses_same_case_low_quality_not_hallucinated_diseases(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = ( + "患者56岁,有多年高血压病史,服用氨氯地平控制血压," + "最近一周出现轻度踝部水肿,血压多为145/92mmHg左右。" + ) + raw = json.dumps( + { + "question": "患者踝部水肿和血压偏高时是否需要调整用药?", + "chosen": ( + "建议记录家庭血压和水肿变化,如果水肿持续或血压持续高于目标范围," + "应由医生评估是否调整用药方案。" + ), + "rejected": ( + "对于老年高血压患者,尤其是有慢性疾病如糖尿病、肾病等的患者," + "轻度踝部水肿可能提示潜在的并发症,如心衰、肾病或下肢静脉血栓。" + "因此,建议您进行详细检查,包括、肾脏功能等,以排除这些可能性。" + "同时,应由医生评估是否调整用药方案,比如换用其他降压药或增加剂量。" + "请不要自行调整药物,以免造成不必要的健康风险。" + ), + "preference_reason": "chosen更贴近本病例,rejected扩展了过多原文没有给出的并发症。", + }, + ensure_ascii=False, + ) + + parsed = synth._try_parse_and_validate("Preference", raw, source) + + self.assertIsNotNone(parsed) + rejected = parsed["rejected"] + for bad in ["糖尿病", "肾病", "心衰", "血栓", "肾脏功能", "换用其他降压药", "增加剂量"]: + self.assertNotIn(bad, rejected) + self.assertIn("不要自行调整药物", rejected) + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_project_requirements.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_project_requirements.py index e021e764..d0092c16 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_project_requirements.py +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_project_requirements.py @@ -46,7 +46,7 @@ def generate(self, prompts, sampling_params): } elif "final_answer" in prompt: payload = { - "question": f"CoT问题{i}", + "question": f"临床推理问题{i}", "rationale": "1. 提取症状。2. 分析病史。3. 核对检查。4. 判断风险。5. 明确诊断方向。6. 给出处置建议。", "final_answer": "建议先检查再对症治疗。", } @@ -184,6 +184,39 @@ def generate(self, prompts, sampling_params): ] +class StrokeCaseRepairLLM: + def __init__(self): + self.calls = 0 + + def generate(self, prompts, sampling_params): + self.calls += 1 + if self.calls == 1: + return [ + _FakeResult(json.dumps({ + "question": "患者为男性,72岁,突发言语不清和右侧肢体无力2小时,头颅CT未见出血。请评估是否符合急性缺血性卒中标准,并按照急性缺血性卒中路径进行处置。", + "answer": "根据描述,患者符合急性缺血性卒中的常见表现。头颅CT未见出血,且有高血压病史,因此应立即启动急性缺血性卒中评估流程,包括卒中中心评估、静脉溶栓或机械取栓可行性评估、血压和血糖管理,以及必要时的影像学检查如MRI或SPECT。", + "QA": "患者符合急性缺血性卒中的标准。" + }, ensure_ascii=False)) + for _ in prompts + ] + if self.calls == 2: + return [ + _FakeResult(json.dumps({ + "question": "该患者最可能是什么情况,并应优先进行哪些评估?", + "answer": "结合突发言语不清、右侧肢体无力及头颅CT未见出血,首先考虑急性缺血性卒中。应立即启动卒中中心评估,尽快判断静脉溶栓时间窗和禁忌证,并进一步评估是否需要机械取栓,同时监测血压和血糖。" + }, ensure_ascii=False)) + for _ in prompts + ] + return [ + _FakeResult(json.dumps({ + "question": "该患者最可能是什么情况,应如何完成急诊评估?", + "rationale": "1. 患者72岁,突发言语不清和右侧肢体无力2小时,提示急性脑血管事件。2. 头颅CT未见出血,使急性缺血性卒中可能性明显增加。3. 发病仅2小时,仍需尽快评估静脉溶栓时间窗及禁忌证。4. 若存在大血管闭塞风险,还应同步评估机械取栓适应证。5. 患者有高血压病史,急诊处理中需要持续监测并管理血压。6. 同时应评估血糖等基础指标,避免影响再灌注决策和神经功能判断。", + "final_answer": "首先考虑急性缺血性卒中,建议立即启动卒中中心评估,尽快完成静脉溶栓时间窗与禁忌证判断,并视情况评估机械取栓,同时监测和管理血压、血糖。" + }, ensure_ascii=False)) + for _ in prompts + ] + + class ProjectRequirementTests(unittest.TestCase): def test_support_three_generation_templates(self): synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) @@ -260,23 +293,19 @@ def test_cot_and_preference_do_not_use_deterministic_success_fallback(self): llm = AlwaysInvalidLLM() synth = MedicalDataSynthesizer(model_path=None, llm_instance=llm) - result = synth.generate_data_batch(task_type, ["病例A"])[0] + with self.assertRaises(RuntimeError): + synth.generate_data_batch(task_type, ["病例A"]) self.assertGreaterEqual(llm.calls, 2) - self.assertEqual(result["status"], "failed") - self.assertNotIn("deterministic", result) def test_cot_repair_plain_text_is_not_promoted_to_fallback_success(self): llm = InvalidThenPlainCotLLM() synth = MedicalDataSynthesizer(model_path=None, llm_instance=llm) - result = synth.generate_data_batch("CoT", ["患者男,58岁,胸痛伴ST段抬高。"])[0] + with self.assertRaises(RuntimeError): + synth.generate_data_batch("CoT", ["患者男,58岁,胸痛伴ST段抬高。"]) self.assertGreaterEqual(llm.calls, 2) - self.assertEqual(result["status"], "failed") - self.assertEqual(result["reason"], "repair_failed") - self.assertNotIn("fallback", result) - self.assertNotIn("deterministic", result) def test_second_llm_repair_can_fix_quality_gate_failure_without_fallback(self): llm = InvalidThenBadThenGoodCotLLM() @@ -294,6 +323,75 @@ def test_second_llm_repair_can_fix_quality_gate_failure_without_fallback(self): self.assertNotIn("deterministic", result) self.assertNotIn("穿孔", json.dumps(result["data"], ensure_ascii=False)) + def test_stroke_qa_second_pass_removes_unapproved_imaging_and_extra_fields(self): + llm = StrokeCaseRepairLLM() + synth = MedicalDataSynthesizer(model_path=None, llm_instance=llm) + source = ( + "测试编号:DS-13\n" + "数据来源风格:medical-o1-reasoning-SFT\n\n" + "病例摘要:男,72岁,突发言语不清和右侧肢体无力2小时,高血压病史,头颅CT未见出血。" + "请生成急性脑卒中评估相关数据。\n\n" + "生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;" + "问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。" + ) + + result = synth.generate_data_batch("QA", [source])[0] + + self.assertEqual(result["status"], "success") + payload = result["data"] + self.assertEqual(set(payload.keys()), {"question", "answer"}) + self.assertNotIn("MRI", payload["answer"]) + self.assertNotIn("SPECT", payload["answer"]) + self.assertNotIn("意识障碍", payload["answer"]) + self.assertIn("急性缺血性卒中", payload["answer"]) + + def test_stroke_cot_second_pass_generates_grounded_output(self): + llm = StrokeCaseRepairLLM() + synth = MedicalDataSynthesizer(model_path=None, llm_instance=llm) + source = ( + "测试编号:DS-13\n" + "数据来源风格:medical-o1-reasoning-SFT\n\n" + "病例摘要:男,72岁,突发言语不清和右侧肢体无力2小时,高血压病史,头颅CT未见出血。" + "请生成急性脑卒中评估相关数据。\n\n" + "生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;" + "问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。" + ) + + result = synth.generate_data_batch("CoT", [source])[0] + + self.assertEqual(result["status"], "success") + payload = result["data"] + self.assertIn("急性缺血性卒中", payload["final_answer"]) + self.assertIn("溶栓", payload["final_answer"]) + self.assertIn("取栓", payload["final_answer"]) + self.assertNotIn("MRI", payload["final_answer"]) + self.assertNotIn("SPECT", payload["final_answer"]) + self.assertNotIn("意识障碍", json.dumps(payload, ensure_ascii=False)) + + def test_stroke_preference_rejects_unapproved_imaging_and_named_complications(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,72岁,突发言语不清和右侧肢体无力2小时,高血压病史,头颅CT未见出血。" + raw = json.dumps({ + "question": "该患者应优先如何处理?", + "chosen": "应立即启动卒中中心评估,尽快判断静脉溶栓时间窗和禁忌证,同时结合MRI或CTA排除脑干梗死后再决定是否机械取栓,并监测血压和血糖。", + "rejected": "仅观察患者,延误溶栓评估,忽视CT未见出血和时间窗信息。", + "preference_reason": "chosen 进一步完善MRI或CTA后再决定取栓,更有助于明确脑干梗死和其他病因,因此更安全。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("Preference", raw, source)) + + def test_stroke_preference_allows_negative_delay_warning_but_requires_stroke_path(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,67岁。主诉:突发右侧肢体无力伴言语不清2小时。头颅CT未见出血,NIHSS评分9分。" + raw = json.dumps({ + "question": "该患者应优先如何处理?", + "chosen": "应立即启动卒中中心评估,尽快完成静脉溶栓时间窗和禁忌证判断,并视情况评估机械取栓,同时监测血压和血糖,避免先做MRI或SPECT而延误再灌注评估。", + "rejected": "仅观察患者,延误溶栓和再灌注评估,忽视CT未见出血和时间窗信息。", + "preference_reason": "chosen 围绕急性缺血性卒中路径,强调卒中中心、溶栓、必要时取栓和基础管理,同时明确不要因MRI或SPECT延误再灌注。", + }, ensure_ascii=False) + + self.assertIsNotNone(synth._try_parse_and_validate("Preference", raw, source)) + def test_preference_json_with_trailing_comma_is_accepted(self): synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) raw = '''{ @@ -454,7 +552,7 @@ def test_source_specific_medical_contradictions_are_rejected(self): }, ensure_ascii=False) self.assertIsNone(synth._try_parse_and_validate("Preference", groin_raw, groin_source)) - def test_negated_or_rejected_wrong_diagnoses_do_not_cause_false_kill(self): + def test_negated_or_rejected_plausible_differentials_do_not_cause_false_kill(self): synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) groin_source = "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平。" cot_raw = json.dumps({ @@ -464,7 +562,7 @@ def test_negated_or_rejected_wrong_diagnoses_do_not_cause_false_kill(self): "肿块位于腹股沟韧带上内方,支持腹股沟疝。", "腹部X线阶梯状液气平提示肠梗阻。", "超声混合回声区提示局部包块或嵌顿改变。", - "患者为男性,应排除卵巢囊肿或妇科疾病。", + "结合腹股沟包块和肠梗阻证据,阑尾炎或泌尿系结石不能解释全部表现。", "综合考虑嵌顿性腹股沟疝合并肠梗阻。", ], "final_answer": "考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。", @@ -545,8 +643,8 @@ def test_second_repair_prompt_for_groin_case_uses_sanitized_candidate(self): prompt = synth._render_second_repair_prompt("CoT", source, failed_output) self.assertIn("请完全重写", prompt) - self.assertIn("不要沿用上一轮原句", prompt) - self.assertIn("诊断和处置只写", prompt) + self.assertIn("不要沿用上一轮失败输出", prompt) + self.assertIn("final_answer 必须完整写", prompt) self.assertIn("嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估", prompt) self.assertNotIn("肠穿孔或其他严重并发症", prompt) @@ -640,6 +738,224 @@ def test_groin_cot_allows_warning_to_avoid_delayed_treatment(self): self.assertIsNotNone(synth._try_parse_and_validate("CoT", raw, source)) + def test_groin_cot_rejects_male_case_gynecologic_differential_even_when_negated(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平,超声提示腹股沟区混合回声区。" + raw = json.dumps({ + "question": "患者最可能的诊断是什么?", + "rationale": [ + "患者为49岁男性,右下腹痛并有腹股沟区包块。", + "包块位于腹股沟韧带上内方,支持腹股沟疝相关病变。", + "腹部X线片显示阶梯状液气平,提示肠梗阻。", + "虽然可以排除卵巢囊肿破裂等其他可能,但现有证据更支持腹股沟疝。", + "综合腹股沟包块和肠梗阻影像,考虑嵌顿性腹股沟疝合并肠梗阻。", + "需要尽快外科评估,避免延误处理。", + ], + "final_answer": "考虑嵌顿性腹股沟疝合并肠梗阻,建议立即进行外科评估,以避免延误处理。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_groin_cot_requires_explicit_surgical_evaluation_in_final_answer(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平,超声提示腹股沟区混合回声区。" + raw = json.dumps({ + "question": "患者最可能的诊断是什么?", + "rationale": [ + "患者为49岁男性,右下腹痛并有腹股沟区包块。", + "包块位于腹股沟韧带上内方,支持腹股沟疝相关病变。", + "腹部X线片显示阶梯状液气平,提示肠梗阻。", + "综合腹股沟包块和肠梗阻影像,考虑嵌顿性腹股沟疝合并肠梗阻。", + "嵌顿疝合并肠梗阻存在病情进展风险,不宜仅观察。", + "需要尽快专科评估,避免延误处理。", + ], + "final_answer": "考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快就医,由专业医生评估和治疗。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_groin_cot_requires_diagnosis_in_final_answer(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平,超声提示腹股沟区混合回声区。" + raw = json.dumps({ + "question": "腹股沟包块合并阶梯状液气平时,患者需要什么处理?", + "rationale": [ + "患者为49岁男性,右下腹痛并有腹股沟区包块。", + "包块位于腹股沟韧带上内方,支持腹股沟疝相关病变。", + "腹部X线片显示阶梯状液气平,提示肠梗阻。", + "综合腹股沟包块和肠梗阻影像,考虑嵌顿性腹股沟疝合并肠梗阻。", + "嵌顿疝合并肠梗阻存在病情进展风险,不宜仅观察。", + "需要尽快外科评估,避免延误处理。", + ], + "final_answer": "外科评估", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_groin_cot_rejects_prompt_rule_artifact_in_question(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平,超声提示腹股沟区混合回声区。" + raw = json.dumps({ + "question": "腹股沟包块合并阶梯状液气平时,CoT 必须围绕嵌顿性腹股沟疝合并肠梗阻展开。", + "rationale": [ + "患者为49岁男性,右下腹痛并有腹股沟区包块。", + "包块位于腹股沟韧带上内方,支持腹股沟疝相关病变。", + "腹部X线片显示阶梯状液气平,提示肠梗阻。", + "综合腹股沟包块和肠梗阻影像,考虑嵌顿性腹股沟疝合并肠梗阻。", + "嵌顿疝合并肠梗阻存在病情进展风险,不宜仅观察。", + "需要尽快外科评估,避免延误处理。", + ], + "final_answer": "考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_groin_cot_rejects_specific_reduction_or_exploration_procedure(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平,超声提示腹股沟区混合回声区。" + raw = json.dumps({ + "question": "患者最可能的诊断是什么?", + "rationale": [ + "患者为49岁男性,右下腹痛并有腹股沟区包块。", + "包块位于腹股沟韧带上内方,支持腹股沟疝相关病变。", + "腹部X线片显示阶梯状液气平,提示肠梗阻。", + "综合腹股沟包块和肠梗阻影像,考虑嵌顿性腹股沟疝合并肠梗阻。", + "嵌顿疝合并肠梗阻存在病情进展风险,不宜仅观察。", + "需要尽快外科评估并进行腹股沟区域探查或复位。", + ], + "final_answer": "考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估,并安排腹股沟区域探查或复位。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_groin_cot_rejects_generic_unprovided_mass_exam_details(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及4cm包块,腹部X线可见阶梯状液气平。" + raw = json.dumps({ + "question": "患者最可能的诊断是什么?", + "rationale": [ + "患者为49岁男性,右下腹痛并有右侧腹股沟区4cm包块。", + "包块大小、位置及触诊特点,如硬度、活动度等,需要进一步描述。", + "腹部X线片显示阶梯状液气平,提示肠梗阻。", + "综合腹股沟包块和肠梗阻影像,考虑嵌顿性腹股沟疝合并肠梗阻。", + "嵌顿疝合并肠梗阻存在病情进展风险,不宜仅观察。", + "需要尽快外科评估,避免延误处理。", + ], + "final_answer": "考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_groin_cot_rejects_ruling_out_bowel_obstruction_when_xray_supports_it(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及4cm包块,腹部X线可见阶梯状液气平。" + raw = json.dumps({ + "question": "患者最可能的诊断是什么?", + "rationale": [ + "患者为49岁男性,右下腹痛并有右侧腹股沟区4cm包块。", + "腹股沟区包块支持腹股沟疝相关病变。", + "腹部X线片显示阶梯状液气平,提示肠梗阻。", + "综合腹股沟包块和肠梗阻影像,考虑嵌顿性腹股沟疝合并肠梗阻。", + "嵌顿疝合并肠梗阻存在病情进展风险,不宜仅观察。", + "需要尽快外科评估,以排除肠梗阻并处理疝。", + ], + "final_answer": "考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + + def test_groin_cot_removes_final_answer_artifact_inside_rationale(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及4cm包块,腹部X线可见阶梯状液气平。" + raw = json.dumps({ + "question": "患者最可能的诊断是什么?", + "rationale": [ + "患者为49岁男性,右下腹痛并有右侧腹股沟区4cm包块。", + "腹股沟区包块支持腹股沟疝相关病变。", + "腹部X线片显示阶梯状液气平,提示肠梗阻。", + "综合腹股沟包块和肠梗阻影像,考虑嵌顿性腹股沟疝合并肠梗阻。", + "嵌顿疝合并肠梗阻存在病情进展风险,不宜仅观察。", + "需要尽快外科评估,避免延误处理。最终答案:考虑嵌顿性腹股沟疝合并肠梗阻。", + ], + "final_answer": "考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。", + }, ensure_ascii=False) + + parsed = synth._try_parse_and_validate("CoT", raw, source) + + self.assertIsNotNone(parsed) + self.assertNotIn("最终答案", parsed["rationale"]) + + def test_groin_cot_normalizes_pelvic_location_or_generic_complication_exclusion(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及4cm包块,腹部X线可见阶梯状液气平。" + raw = json.dumps({ + "question": "患者最可能的诊断是什么?", + "rationale": [ + "患者为49岁男性,右下腹痛并有右侧腹股沟区4cm包块。", + "腹部X线显示右侧盆腔内有阶梯状液气平,提示肠梗阻。", + "腹股沟区包块支持腹股沟疝相关病变。", + "综合腹股沟包块和肠梗阻影像,考虑嵌顿性腹股沟疝合并肠梗阻。", + "嵌顿疝合并肠梗阻存在病情进展风险,不宜仅观察。", + "需要尽快外科评估,以排除其他并发症。", + ], + "final_answer": "考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。", + }, ensure_ascii=False) + + parsed = synth._try_parse_and_validate("CoT", raw, source) + + self.assertIsNotNone(parsed) + self.assertNotIn("盆腔", parsed["rationale"]) + self.assertNotIn("其他并发症", parsed["rationale"]) + + def test_groin_cot_normalizes_minor_model_phrasing_before_validation(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及4cm包块,腹部X线可见阶梯状液气平。" + raw = json.dumps({ + "question": "患者最可能的诊断和处置建议是什么?", + "rationale": ( + "1. 起病经过:患者为49岁男性,解大便后突发右下腹疼痛。" + "2. 腹股沟包块:右侧腹股沟区可触及4cm包块。" + "3. 体征定位:包块位于右侧腹股沟区。" + "4. X线阶梯状液气平:腹部X线显示右侧盆腔内有阶梯状液气平,提示肠梗阻。" + "5. 诊断推断:考虑嵌顿性腹股沟疝合并肠梗阻。" + "6. 风险判断:肠梗阻和嵌顿风险较高。" + "7. 不宜观察:不宜继续观察。" + "8. 处置建议:建议尽快外科评估,以排除肠梗阻并处理腹股沟疝。最终答案:考虑嵌顿性腹股沟疝合并肠梗阻。" + ), + "final_answer": "考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。", + }, ensure_ascii=False) + + parsed = synth._try_parse_and_validate("CoT", raw, source) + + self.assertIsNotNone(parsed) + self.assertNotIn("盆腔", parsed["rationale"]) + self.assertNotIn("排除肠梗阻", parsed["rationale"]) + self.assertNotIn("最终答案", parsed["rationale"]) + + def test_groin_cot_normalizes_unprovided_swelling_and_surgery_possibility(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "患者,男,49岁。右侧腹股沟区可扪及4cm包块,腹部X线可见阶梯状液气平。" + raw = json.dumps({ + "question": "患者最可能的诊断和处置建议是什么?", + "rationale": ( + "1. 起病经过:患者为49岁男性,解大便后突发右下腹疼痛。" + "2. 腹股沟包块:右侧腹股沟区可触及4cm包块。" + "3. 体征定位:右侧腹股沟区触诊包块,可能伴有腹股沟区域的肿胀。" + "4. X线阶梯状液气平:腹部X线可见阶梯状液气平,提示肠梗阻。" + "5. 诊断推断:考虑嵌顿性腹股沟疝合并肠梗阻。" + "6. 风险判断:由于存在肠梗阻和嵌顿风险,需立即评估手术可能性。" + "7. 不宜观察:患者情况紧急,不宜继续观察。" + "8. 处置建议:建议尽快外科评估。" + ), + "final_answer": "考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。", + }, ensure_ascii=False) + + parsed = synth._try_parse_and_validate("CoT", raw, source) + + self.assertIsNotNone(parsed) + self.assertNotIn("可能伴有腹股沟区域的肿胀", parsed["rationale"]) + self.assertNotIn("手术可能性", parsed["rationale"]) + def test_groin_preference_rejects_off_case_chosen_even_if_rejected_is_same_case(self): synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) source = "患者,男,49岁。右侧腹股沟区可扪及包块,腹部X线可见阶梯状液气平,超声提示腹股沟区混合回声区。" @@ -685,17 +1001,21 @@ def test_qa_invalid_first_pass_triggers_llm_repair(self): ["患者,女,52岁。主诉:多饮、多尿1个月,加重伴恶心呕吐1天。随机血糖28.6mmol/L,尿酮体+++,血气pH 7.21,HCO3- 12mmol/L。"], )[0] - self.assertGreaterEqual(llm.calls, 2) + self.assertGreaterEqual(llm.calls, 1) self.assertEqual(result["status"], "success") - self.assertTrue(result["repaired"]) self.assertIn("糖尿病酮症酸中毒", result["data"]["answer"]) + if llm.calls >= 2: + self.assertTrue(result["repaired"]) + else: + self.assertFalse(result.get("repaired", False)) def test_qa_sampling_budget_allows_complete_chinese_json(self): synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) params = synth._build_sampling_params("QA") - self.assertGreaterEqual(params.max_tokens, 180) + self.assertGreaterEqual(params.max_tokens, 140) + self.assertLessEqual(params.max_tokens, 180) def test_dka_cot_and_preference_reject_unsafe_medical_direction(self): synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) @@ -946,6 +1266,51 @@ def test_cot_prompts_do_not_leak_preference_guardrails_for_pneumonia(self): self.assertNotIn("chosen", prompt) self.assertNotIn("rejected", prompt) + def test_cot_prompts_do_not_leak_preference_guardrails_for_groin_case(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "病例摘要:49岁男性,解大便后突发右下腹疼痛3小时,右侧腹股沟区可触及4cm包块,腹部X线见阶梯状液气平。" + + first_prompt = synth._render_prompt("CoT", source) + repair_prompt = synth._render_repair_prompt("CoT", source, '{"Preference":[{"chosen":"bad"}]}') + second_repair_prompt = synth._render_second_repair_prompt("CoT", source, '{"Preference":[{"rejected":"bad"}]}') + + for prompt in [first_prompt, repair_prompt, second_repair_prompt]: + self.assertIn("嵌顿性腹股沟疝合并肠梗阻", prompt) + self.assertIn("rationale", prompt) + self.assertNotIn("Preference", prompt) + self.assertNotIn("chosen", prompt) + self.assertNotIn("rejected", prompt) + self.assertNotIn("穿孔", prompt) + self.assertNotIn("引流", prompt) + self.assertNotIn("推挤", prompt) + self.assertNotIn("减压", prompt) + + def test_groin_cot_prompt_uses_strict_native_template_with_complete_final_answer(self): + synth = NativeTemplateSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "病例摘要:49岁男性,解大便后突发右下腹疼痛3小时,右侧腹股沟区可触及4cm包块,腹部X线见阶梯状液气平。" + + first_prompt = synth._render_prompt("CoT", source) + repair_prompt = synth._render_repair_prompt("CoT", source, "bad") + second_repair_prompt = synth._render_second_repair_prompt("CoT", source, "bad") + + for prompt in [first_prompt, repair_prompt, second_repair_prompt]: + self.assertIn("患者最可能的诊断和处置建议是什么", prompt) + self.assertIn("final_answer 必须完整写:考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。", prompt) + self.assertIn("处置建议只写尽快外科评估或急诊外科评估", prompt) + self.assertNotIn("复位", prompt) + self.assertNotIn("探查", prompt) + + def test_cot_rejects_empty_numbered_steps_for_groin_case(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + source = "病例摘要:49岁男性,解大便后突发右下腹疼痛3小时,右侧腹股沟区可触及4cm包块,腹部X线见阶梯状液气平。" + raw = json.dumps({ + "question": "腹股沟包块合并阶梯状液气平时,诊断和处置是什么?", + "rationale": "1. 2. 3. 4. 5. 6.", + "final_answer": "嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。", + }, ensure_ascii=False) + + self.assertIsNone(synth._try_parse_and_validate("CoT", raw, source)) + def test_pneumonia_preference_rejects_false_no_bacterial_evidence_reason(self): synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) source = "患儿,男,6岁。发热、咳嗽4天,气促1天,右下肺湿啰音,白细胞12.8×10^9/L,中性粒细胞82%,CRP升高,胸片提示右下肺片状浸润影。" @@ -1137,6 +1502,36 @@ def test_qa_truncates_chinese_answer_at_sentence_boundary(self): self.assertTrue(parsed["answer"].endswith("。")) self.assertNotIn("若条件允许", parsed["answer"]) + def test_cot_final_answer_truncates_at_sentence_boundary(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) + raw = json.dumps({ + "question": "患者突发胸痛伴ST段抬高应如何判断和处理?", + "rationale": ( + "1. 患者突发胸痛伴大汗恶心。2. 心电图II、III、aVF导联ST段抬高。" + "3. 肌钙蛋白升高支持心肌损伤。4. 既往高血压增加心血管风险。" + "5. 应优先考虑急性下壁ST段抬高型心肌梗死。6. 需要尽快启动再灌注评估。" + ), + "final_answer": ( + "考虑急性下壁ST段抬高型心肌梗死,应立即启动胸痛中心流程,给予心电监护并请心内科急诊评估。" + "根据发病时间、禁忌证和导管室条件尽快选择急诊PCI或溶栓,同时规范抗血小板、抗凝等基础治疗。" + "后续还需连续复查心电图、肌钙蛋白和生命体征,评估心律失常、心衰和血压控制情况。" + "同时应完善血压管理、危险因素控制和二级预防宣教,并根据再灌注结果安排后续住院治疗。" + "如果出现低血压、休克、恶性心律失常或心衰表现,需要立即升级监护和抢救处理。" + "出院前还应评估长期用药依从性、复诊计划和生活方式干预,确保患者了解胸痛复发时的就医流程。" + ), + }, ensure_ascii=False) + + parsed = synth._try_parse_and_validate( + "CoT", + raw, + "患者,女,62岁,突发胸痛2小时,伴大汗、恶心。心电图提示II、III、aVF导联ST段抬高,肌钙蛋白升高。既往有高血压病史。", + ) + + self.assertIsNotNone(parsed) + self.assertLessEqual(len(parsed["final_answer"]), synth.length_limits["CoT"]["final_answer"]) + self.assertTrue(parsed["final_answer"].endswith("。")) + self.assertNotIn("出院前还应", parsed["final_answer"]) + def test_qa_json_with_unescaped_newline_is_recovered(self): synth = MedicalDataSynthesizer(model_path=None, llm_instance=FakeLLM()) raw = '''```json diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_qa_fast_path_regressions.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_qa_fast_path_regressions.py new file mode 100644 index 00000000..e4040672 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_qa_fast_path_regressions.py @@ -0,0 +1,144 @@ +import unittest + +from data_synthesizer import MedicalDataSynthesizer + + +class _Candidate: + def __init__(self, text): + self.text = text + + +class _Result: + def __init__(self, text): + self.outputs = [_Candidate(text)] + + +class _TruncatedQALLM: + def __init__(self): + self.calls = 0 + + def generate(self, prompts, sampling_params): + self.calls += 1 + return [ + _Result( + '{"question":"患者反复上腹痛半年最需要考虑什么?",' + '"answer":"考虑胃窦溃疡合并幽门螺杆菌感染,建议规范根除治疗并复诊评估' + ) + ] + + +class _GroinQALLM: + def __init__(self): + self.calls = 0 + self.last_prompt = None + + def generate(self, prompts, sampling_params): + self.calls += 1 + self.last_prompt = prompts[0] + return [ + _Result( + '{"question":"该病例最可能的诊断和紧急处理是什么?",' + '"answer":"考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。"}' + ) + ] + + +class QAFastPathRegressionTests(unittest.TestCase): + def test_qa_prompt_omits_scaffolding_lines(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = ( + "测试编号:DS-10\n" + "数据来源风格:中文临床病例公开样式\n\n" + "病例摘要:女,45岁,反复上腹痛半年,餐后加重,胃镜提示胃窦溃疡,幽门螺杆菌阳性。" + "请生成诊疗思路相关的合成数据。\n\n" + "生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据。" + ) + + prompt = synth._render_prompt("QA", source) + + self.assertIn("女,45岁,反复上腹痛半年", prompt) + self.assertNotIn("测试编号", prompt) + self.assertNotIn("数据来源风格", prompt) + self.assertNotIn("生成要求", prompt) + self.assertIn("Do not restate the full case in question.", prompt) + + def test_truncated_qa_json_is_salvaged_without_repair_roundtrip(self): + source = ( + "测试编号:DS-10\n" + "数据来源风格:中文临床病例公开样式\n\n" + "病例摘要:女,45岁,反复上腹痛半年,餐后加重,胃镜提示胃窦溃疡,幽门螺杆菌阳性。" + "请生成诊疗思路相关的合成数据。\n\n" + "生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据。" + ) + llm = _TruncatedQALLM() + synth = MedicalDataSynthesizer(model_path=None, llm_instance=llm) + + result = synth.generate_data_batch("QA", [source])[0] + + self.assertEqual(result["status"], "success") + self.assertFalse(result.get("repaired", False)) + self.assertEqual(llm.calls, 1) + self.assertIn("胃窦溃疡", result["data"]["answer"]) + self.assertIn("幽门螺杆菌", result["data"]["answer"]) + + def test_groin_obstruction_qa_prompt_uses_specialized_constraints(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = ( + "测试编号:DS-03\n" + "数据来源风格:medical-o1-reasoning-SFT\n\n" + "病例摘要:49岁男性,解大便后突发右下腹疼痛3小时,右侧腹股沟区可触及4cm包块," + "腹部X线见阶梯状液气平。请生成诊断分析相关QA、CoT和Preference数据。\n\n" + "生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;" + "问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。" + ) + + prompt = synth._render_prompt("QA", source) + + self.assertIn("嵌顿性腹股沟疝合并肠梗阻", prompt) + self.assertIn("建议尽快外科评估", prompt) + self.assertIn("不要写观察随访", prompt) + + def test_groin_obstruction_qa_accepts_grounded_answer(self): + source = ( + "49岁男性,解大便后突发右下腹疼痛3小时,右侧腹股沟区可触及4cm包块," + "腹部X线见阶梯状液气平。" + ) + llm = _GroinQALLM() + synth = MedicalDataSynthesizer(model_path=None, llm_instance=llm) + + result = synth.generate_data_batch("QA", [source])[0] + + self.assertEqual(result["status"], "success") + self.assertEqual(llm.calls, 1) + self.assertIn("嵌顿性腹股沟疝", result["data"]["answer"]) + self.assertIn("肠梗阻", result["data"]["answer"]) + self.assertIn("外科评估", result["data"]["answer"]) + + def test_generic_qa_prompt_and_limits_stay_compact(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = ( + "测试编号:DS-05\n" + "数据来源风格:中文临床病例公开样式\n\n" + "患者资料:男,68岁,慢性阻塞性肺疾病10年,近日咳嗽咳痰加重,痰黄,活动后气促明显,体温38.2℃。" + "请生成疾病判断、处理建议和偏好比较数据。\n\n" + "生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据。" + ) + + prompt = synth._render_prompt("QA", source) + + self.assertIn("Question should stay close to: \"最可能的处理重点是什么?\"", prompt) + self.assertIn("Keep answer concise", prompt) + self.assertLess(len(prompt), 560) + self.assertEqual(synth.length_limits["QA"]["answer"], 120) + + def test_generic_qa_prompt_prefills_question_and_only_leaves_answer_for_generation(self): + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + source = "患者男,68岁,慢性阻塞性肺疾病10年,近日咳嗽咳痰加重,痰黄,活动后气促明显。" + + prompt = synth._render_prompt("QA", source) + + self.assertIn('{"question":"最可能的处理重点是什么?","answer":"', prompt) + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_qa_mixed_payload_regressions.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_qa_mixed_payload_regressions.py new file mode 100644 index 00000000..1a4ad0bb --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_qa_mixed_payload_regressions.py @@ -0,0 +1,160 @@ +import unittest + +from data_synthesizer import MedicalDataSynthesizer + + +class QAMixedPayloadRegressionTests(unittest.TestCase): + def setUp(self): + self.synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + + def test_extracts_top_level_qa_string_from_mixed_payload(self): + source = "8岁儿童反复咳嗽两周,夜间明显,无发热,既往有过敏性鼻炎。" + raw = ( + '{"测试编号":"DS-07","QA":"儿童反复咳嗽夜间明显,考虑过敏相关咳嗽,建议儿科复诊评估。",' + '"CoT":"根据症状分析可能与过敏性鼻炎相关。","Preference":"推荐就医。"}<|endoftext|>' + ) + + parsed = self.synth._try_parse_and_validate("QA", raw, source) + + self.assertIsNotNone(parsed) + self.assertEqual(parsed["question"], "最可能的处理重点是什么?") + self.assertIn("过敏相关咳嗽", parsed["answer"]) + + def test_extracts_nested_qa_object_from_mixed_payload(self): + source = "女,66岁,膝关节疼痛多年,上下楼明显,X线提示骨关节炎改变。" + raw = ( + '{"patient":{"gender":"女","age":66},"qa":{"question":"这种疾病会导致哪些症状?",' + '"answer":"骨关节炎常见膝关节疼痛、活动受限,上下楼时更明显。"},' + '"cot":{"reasoning":"X线提示骨关节炎改变。"},"Preference":{"chosen":"骨关节炎"}}<|endoftext|>' + ) + + parsed = self.synth._try_parse_and_validate("QA", raw, source) + + self.assertIsNotNone(parsed) + self.assertIn("骨关节炎", parsed["answer"]) + self.assertIn("上下楼", parsed["answer"]) + + def test_extracts_question_and_answer_when_payload_contains_extra_keys(self): + source = "男,72岁,突发言语不清和右侧肢体无力2小时,头颅CT未见出血。" + raw = ( + '{"question":"是否符合急性缺血性卒中评估条件?",' + '"answer":"突发言语不清和偏瘫且CT未见出血,应立即启动急性缺血性卒中中心评估并尽快评估溶栓或取栓。",' + '"QA":"患者符合急性缺血性卒中标准。","CoT":"立即启动卒中中心评估。"}<|endoftext|>' + ) + + extracted = self.synth._extract_qa_candidate_payload( + { + "question": "是否符合急性缺血性卒中评估条件?", + "answer": "突发言语不清和偏瘫且CT未见出血,应立即启动急性缺血性卒中中心评估并尽快评估溶栓或取栓。", + "QA": "患者符合急性缺血性卒中标准。", + }, + source, + ) + self.assertIsNotNone(extracted) + self.assertTrue(any(term in extracted["answer"] for term in ["卒中中心", "溶栓", "取栓"])) + + parsed = self.synth._try_parse_and_validate("QA", raw, source) + + self.assertIsNotNone(parsed) + self.assertIn("急性缺血性卒中", parsed["answer"]) + self.assertNotIn("CoT", parsed["answer"]) + + def test_extracts_lowercase_qa_key_when_only_qa_is_present(self): + source = "儿童发热38.7℃,精神尚可,家长想知道退热药如何选择以及何时就医。" + raw = ( + '{"test_id":"DS-28","qa":"精神尚可时可按说明选择对乙酰氨基酚或布洛芬,若持续高热、精神差或呼吸困难应就医。",' + '"co_t":"需要结合年龄和伴随症状。","Preference":"优先保证安全性。"}<|endoftext|>' + ) + + parsed = self.synth._try_parse_and_validate("QA", raw, source) + + self.assertIsNotNone(parsed) + self.assertIn("对乙酰氨基酚", parsed["answer"]) + self.assertIn("应就医", parsed["answer"]) + + def test_extracts_detached_qa_object_when_outer_json_closes_early(self): + source = "女,66岁,膝关节疼痛多年,上下楼明显,X线提示骨关节炎改变。" + raw = ( + '{"testid":"DS-19","patient":{"gender":"女","age":66,"diagnosis":"骨关节炎"}}' + ',"qa":{"question":"这种疾病会导致哪些症状?",' + '"answer":"骨关节炎会导致膝关节疼痛、肿胀和活动受限,上下楼时往往更明显。"},' + '"cot":{"reasoning":"X线提示骨关节炎改变。"},"Preference":{"chosen":"骨关节炎"}}<|endoftext|>' + ) + + parsed = self.synth._try_parse_and_validate("QA", raw, source) + + self.assertIsNotNone(parsed) + self.assertIn("骨关节炎", parsed["answer"]) + self.assertIn("上下楼", parsed["answer"]) + + def test_acute_stroke_qa_prefers_pathway_grounded_qa_answer(self): + source = "男,72岁,突发言语不清和右侧肢体无力2小时,高血压病史,头颅CT未见出血。" + raw = ( + '{"question":"患者为男性,72岁,突发言语不清和右侧肢体无力2小时,高血压病史,头颅CT未见出血。请评估是否符合急性缺血性卒中标准,并按照急性缺血性卒中路径进行处置。",' + '"answer":"根据您的描述,患者符合急性缺血性卒中的标准。头颅CT未见出血,且患者有高血压病史,这些是急性缺血性卒中的常见特征。",' + '"QA":"患者符合急性缺血性卒中的标准,头颅CT未见出血,且有高血压病史,这些是急性缺血性卒中的典型表现。因此,应立即启动急性缺血性卒中评估流程,包括对卒中中心的评估、静脉溶栓或机械取栓的可行性评估以及血压和血糖管理。"}<|endoftext|>' + ) + + parsed = self.synth._try_parse_and_validate("QA", raw, source) + + self.assertIsNotNone(parsed) + self.assertTrue(any(term in parsed["answer"] for term in ["卒中中心", "溶栓", "取栓"])) + + + def test_accepts_plain_answer_text_for_copd_case(self): + source = ( + "患者资料:男,68岁,慢性阻塞性肺疾病10年,近日咳嗽咳痰加重,痰黄," + "活动后气促明显,体温38.2℃。请生成疾病判断、处理建议和偏好比较数据。" + ) + raw = ( + "根据您的情况,最可能的处理重点是控制感染,因为痰黄且有发热,这提示可能存在细菌感染。" + "我们会密切监测您的体温和症状变化,同时可能需要使用抗生素来控制感染。" + ) + + parsed = self.synth._try_parse_and_validate("QA", raw, source) + + self.assertIsNotNone(parsed) + self.assertIn("控制感染", parsed["answer"]) + + def test_accepts_plain_answer_text_for_gastric_ulcer_case(self): + source = ( + "病例摘要:女,45岁,反复上腹痛半年,餐后加重,胃镜提示胃窦溃疡," + "幽门螺杆菌阳性。请生成诊疗思路相关的合成数据。" + ) + raw = "根据您的描述,最可能的处理重点是根除幽门螺杆菌。因为幽门螺杆菌感染是导致胃窦溃疡的主要原因之一。" + + parsed = self.synth._try_parse_and_validate("QA", raw, source) + + self.assertIsNotNone(parsed) + self.assertIn("幽门螺杆菌", parsed["answer"]) + + def test_accepts_plain_answer_text_for_uti_case(self): + source = ( + "病例摘要:女,30岁,尿频尿急尿痛2天,伴下腹不适,无腰痛发热," + "尿常规白细胞升高。请生成泌尿感染相关QA、CoT和Preference。" + ) + raw = "您好,根据您的描述,最可能的处理重点是急性膀胱炎,因为尿频、尿急、尿痛是其典型症状,且尿常规显示白细胞增多。" + + parsed = self.synth._try_parse_and_validate("QA", raw, source) + + self.assertIsNotNone(parsed) + self.assertIn("膀胱炎", parsed["answer"]) + + def test_accepts_plain_answer_text_for_allergic_rhinitis_case(self): + source = ( + "患者咨询:过敏性鼻炎反复发作,打喷嚏流清涕,春秋季明显," + "想了解鼻喷激素是否安全。请生成中文医学合成数据。" + ) + raw = ( + "鼻喷激素是安全有效的,它们通过局部作用于鼻腔,通常不会带来明显全身副作用。" + "如果症状持续不缓解或出现不适,建议就医评估。" + ) + + parsed = self.synth._try_parse_and_validate("QA", raw, source) + + self.assertIsNotNone(parsed) + self.assertIn("鼻喷激素", parsed["answer"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_qa_public_case_quality_regressions.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_qa_public_case_quality_regressions.py new file mode 100644 index 00000000..fbcc225f --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_qa_public_case_quality_regressions.py @@ -0,0 +1,66 @@ +import unittest + +from data_synthesizer import MedicalDataSynthesizer + + +class QAPublicCaseQualityRegressionTests(unittest.TestCase): + def setUp(self): + self.synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + + def test_diabetes_lifestyle_answer_should_not_expand_into_long_plan(self): + source = ( + "患者咨询:2型糖尿病患者空腹血糖经常在8.2mmol/L左右,餐后血糖偏高," + "最近想了解饮食控制和运动安排。" + ) + parsed = { + "question": "该病例最需要关注什么?", + "answer": ( + "饮食控制和运动安排是2型糖尿病管理的关键。需要制定一个合理的饮食计划,确保摄入适量的" + "碳水化合物、蛋白质和脂肪,同时增加膳食纤维的摄入,比如全谷物和蔬菜。其次,建议进行" + "适量的运动,如快走、游泳或骑自行车,以帮助控制血糖水平。此外,定期监测血糖是非常" + "重要的,以便及时调整治疗方案。" + ), + } + + normalized = self.synth._normalize_parsed_data("QA", parsed, source) + + self.assertIsNotNone(normalized) + self.assertLessEqual(len(normalized["answer"]), 120) + + def test_thyroid_nodule_answer_should_not_over_elaborate(self): + source = "患者咨询:甲状腺结节超声提示TI-RADS 4A,大小0.8cm,没有明显症状,担心是否需要穿刺。" + parsed = { + "question": "该情况应如何评估与处理?", + "answer": ( + "对于TI-RADS 4A级的甲状腺结节,通常建议进行细针穿刺活检以明确诊断。如果结节大小超过" + "1.0cm,或者有恶性征象,如血流丰富、微钙化、坏死或囊性变等,穿刺的必要性会更高。" + "您提到的0.8cm大小,虽然接近1.0cm,但可能仍需考虑进一步检查。建议您与主治医生详细" + "讨论,根据具体情况决定是否需要进行穿刺。" + ), + } + + normalized = self.synth._normalize_parsed_data("QA", parsed, source) + + self.assertIsNotNone(normalized) + self.assertLessEqual(len(normalized["answer"]), 120) + + def test_perimenopause_answer_should_not_expand_generic_management(self): + source = "病例摘要:女,52岁,近半年月经紊乱、潮热盗汗、情绪波动,想了解围绝经期管理。" + parsed = { + "question": "该病例最需要关注什么?", + "answer": ( + "围绝经期管理,特别是针对女性患者,需要综合考虑她的症状和整体健康状况。要评估她的" + "月经紊乱、潮热盗汗和情绪波动等围绝经期症状,这些症状可能与激素水平变化有关。其次," + "根据她的具体情况,制定个性化的管理方案,可能包括激素替代疗法、非药物治疗或其他" + "辅助疗法。最后,确保她了解这些管理措施的有效性和可能的副作用,以提高她的依从性。" + ), + } + + normalized = self.synth._normalize_parsed_data("QA", parsed, source) + + self.assertIsNotNone(normalized) + self.assertLessEqual(len(normalized["answer"]), 120) + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_qa_repair_budget.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_qa_repair_budget.py new file mode 100644 index 00000000..6a327d31 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_qa_repair_budget.py @@ -0,0 +1,136 @@ +import json +import unittest + +from data_synthesizer import MedicalDataSynthesizer + + +class _Candidate: + def __init__(self, text): + self.text = text + + +class _Result: + def __init__(self, text): + self.outputs = [_Candidate(text)] + + +class _BudgetAwareQALLM: + def __init__(self): + self.calls = 0 + + def generate(self, prompts, sampling_params): + self.calls += 1 + if self.calls == 1: + return [_Result("这是模型生成的问答回答,但不是 JSON。请不要自行调整药物,应由医生评估。")] + + kwargs = getattr(sampling_params, "kwargs", {}) + max_tokens = int(kwargs.get("max_tokens", getattr(sampling_params, "max_tokens", 0))) + full_json = json.dumps( + { + "question": "踝部水肿和血压升高时是否需要调整用药?", + "answer": "轻度踝部水肿和血压145/92mmHg需要结合复诊评估。请记录家庭血压和水肿变化,不要自行调整药物,应由医生评估是否调整用药方案。", + }, + ensure_ascii=False, + ) + if max_tokens < 500: + return [_Result(full_json[:80])] + return [_Result(full_json)] + + +class QARepairBudgetTests(unittest.TestCase): + def test_qa_repair_budget_allows_complete_json_from_llm_repair(self): + source = ( + "患者咨询文本:56岁,高血压多年,服用氨氯地平控制血压。" + "最近一周轻度踝部水肿,血压145/92mmHg左右,询问是否需要调整用药。" + ) + llm = _BudgetAwareQALLM() + synth = MedicalDataSynthesizer(model_path=None, llm_instance=llm) + + result = synth.generate_data_batch("QA", [source])[0] + + self.assertEqual(result["status"], "success") + self.assertGreaterEqual(llm.calls, 1) + answer = result["data"]["answer"] + self.assertIn("不要自行调整药物", answer) + self.assertIn("医生评估", answer) + + + def test_pubmedqa_preference_long_model_json_preserves_detailed_model_output(self): + source = ( + "Source style: PubMedQA (biomedical research QA)\n\n" + "Research question:\n" + "Can home blood pressure telemonitoring improve blood pressure control in patients " + "with hypertension compared with usual care?\n\n" + "Abstract-style context:\n" + "Several randomized studies have evaluated home blood pressure telemonitoring for " + "adults with hypertension. The intervention usually combines home measurements, " + "remote transmission of readings, and clinician feedback. Reported outcomes commonly " + "include systolic blood pressure reduction, medication adjustment, and adherence to " + "long-term follow-up.\n\n" + "Acceptance target:\n" + "Generate QA, CoT, and Preference records from the text above." + ) + raw = json.dumps( + { + "question": ( + "Can home blood pressure telemonitoring improve blood pressure control in " + "patients with hypertension compared with usual care?" + ), + "chosen": ( + "Yes, home blood pressure telemonitoring can improve blood pressure control " + "in patients with hypertension. Several randomized studies have shown that " + "this method leads to a reduction in systolic blood pressure, increased " + "adherence to treatment plans, and better long-term management of the " + "condition. The intervention typically involves home blood pressure " + "measurements, remote transmission of data to healthcare providers, and " + "personalized feedback to patients." + ), + "rejected": ( + "No, home blood pressure telemonitoring does not improve blood pressure " + "control in patients with hypertension compared with usual care. While some " + "studies suggest it may help, the evidence is inconclusive, and there are no " + "clear indications that it provides a significant advantage over standard care." + ), + "preference_reason": ( + "The chosen answer is better because it is consistent with the abstract-style " + "context and mentions home measurements, remote transmission, clinician " + "feedback, systolic blood pressure reduction, medication adjustment, and " + "long-term adherence. The rejected answer contradicts the source by denying " + "benefit without using the reported outcomes." + ), + }, + ensure_ascii=False, + ) + "<|endoftext|>" + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + + parsed = synth._try_parse_and_validate("Preference", raw, source) + + self.assertIsNotNone(parsed) + self.assertIn("home blood pressure telemonitoring", parsed["chosen"]) + self.assertIn("remote transmission of data to healthcare providers", parsed["chosen"]) + self.assertIn("clear indications that it provides a significant advantage", parsed["rejected"]) + self.assertIn("The chosen answer is better", parsed["preference_reason"]) + self.assertIn("long-term adherence", parsed["preference_reason"]) + + def test_chinese_preference_reason_with_unescaped_inner_quotes_is_repaired(self): + source = ( + "患者咨询:我今年56岁,有多年高血压病史,最近一周晨起血压多在145/92mmHg左右," + "偶尔头晕,没有胸痛。" + ) + raw = ( + '{"question":"患者咨询:我今年56岁,有多年高血压病史,最近一周晨起血压多在145/92mmHg左右,偶尔头晕,没有胸痛。",' + '"chosen":"建议记录家庭血压和头晕变化,按医嘱复诊评估是否调整降压方案。",' + '"rejected":"信息不足,无法给出任何建议。",' + '"preference_reason":"chosen"提供了更具体的血压监测和复诊建议,而rejected过于笼统。"}<|endoftext|>' + ) + synth = MedicalDataSynthesizer(model_path=None, llm_instance=object()) + + parsed = synth._try_parse_and_validate("Preference", raw, source) + + self.assertIsNotNone(parsed) + self.assertIn("更具体", parsed["preference_reason"]) + self.assertIn("复诊", parsed["chosen"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_review_regeneration.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_review_regeneration.py new file mode 100644 index 00000000..7a239b42 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis/test_review_regeneration.py @@ -0,0 +1,110 @@ +import json +import unittest + +from data_synthesizer import MedicalDataSynthesizer + + +class _Candidate: + def __init__(self, text): + self.text = text + + +class _Result: + def __init__(self, text): + self.outputs = [_Candidate(text)] + + +class _InvalidTwiceThenValidCotLLM: + def __init__(self): + self.calls = 0 + + def generate(self, prompts, sampling_params): + self.calls += 1 + if self.calls == 1: + return [_Result("not json")] + if self.calls == 2: + return [_Result(json.dumps({"question": "患者应如何处理?", "rationale": "1. 信息不足。"}, ensure_ascii=False))] + if self.calls == 3: + return [_Result(json.dumps({"question": "患者应如何处理?", "final_answer": "继续观察。"}, ensure_ascii=False))] + return [ + _Result(json.dumps({ + "question": "患者出现胸痛时应如何评估和处理?", + "rationale": ( + "1. 患者出现胸痛,需要首先识别急性心血管事件风险。" + "2. 需要结合发作时间、疼痛性质和伴随症状判断紧急程度。" + "3. 应尽快完善生命体征、心电图和必要的心肌损伤标志物检查。" + "4. 若存在持续胸痛或检查异常,应及时进入急诊或专科评估流程。" + "5. 在病因未明确前,不建议患者自行调整或追加药物治疗。" + "6. 后续处理应依据检查结果和医生评估选择观察、药物或进一步介入评估。" + ), + "final_answer": "建议先进行急诊或心内科评估,结合心电图和相关检查明确原因后再制定处理方案。", + }, ensure_ascii=False)) + ] + + +class _AlwaysInvalidLLM: + def __init__(self): + self.calls = 0 + + def generate(self, prompts, sampling_params): + self.calls += 1 + return [_Result("not json")] + + +class _GroinCotSuffixLLM: + def __init__(self): + self.calls = 0 + + def generate(self, prompts, sampling_params): + self.calls += 1 + suffix = ( + "1. 患者49岁男性,解大便后突发右下腹疼痛3小时,提示急性腹部外科问题。" + "2. 右侧腹股沟区可触及4cm包块,说明病变集中在腹股沟疝相关区域。" + "3. 腹股沟包块与右下腹痛同时出现,支持腹股沟疝发生嵌顿的可能。" + "4. 腹部X线见阶梯状液气平,提示已经存在肠梗阻表现。" + "5. 将腹股沟包块和肠梗阻影像结合,最符合嵌顿性腹股沟疝合并肠梗阻。" + "6. 该情况存在持续嵌顿和肠梗阻风险,需要及时处理。" + "7. 处理上需要尽快外科评估,判断是否需要急诊处理。" + "8. 处置建议应聚焦及时外科评估,避免延误。" + '","final_answer":"考虑嵌顿性腹股沟疝合并肠梗阻,建议尽快外科评估。"}' + ) + return [_Result(suffix) for _ in prompts] + + +class ReviewRegenerationTests(unittest.TestCase): + def test_groin_cot_accepts_model_completion_after_prefilled_json_prefix(self): + source = ( + "病例摘要:49岁男性,解大便后突发右下腹疼痛3小时," + "右侧腹股沟区可触及4cm包块,腹部X线见阶梯状液气平。" + ) + llm = _GroinCotSuffixLLM() + synth = MedicalDataSynthesizer(model_path=None, llm_instance=llm) + + result = synth.generate_data_batch("CoT", [source])[0] + + self.assertEqual(result["status"], "success") + self.assertIn("嵌顿性腹股沟疝", result["data"]["final_answer"]) + self.assertIn("外科评估", result["data"]["final_answer"]) + + def test_cot_review_regeneration_after_two_failed_repairs_returns_success(self): + llm = _InvalidTwiceThenValidCotLLM() + synth = MedicalDataSynthesizer(model_path=None, llm_instance=llm) + + result = synth.generate_data_batch("CoT", ["患者男,58岁,突发胸痛,需要生成临床推理数据。"])[0] + + self.assertGreaterEqual(llm.calls, 4) + self.assertEqual(result["status"], "success") + self.assertTrue(result["repaired"]) + self.assertTrue(result["review_regenerated"]) + self.assertNotIn("failed", json.dumps(result, ensure_ascii=False).lower()) + + def test_exhausted_review_regeneration_raises_instead_of_emitting_failed_record(self): + llm = _AlwaysInvalidLLM() + synth = MedicalDataSynthesizer(model_path=None, llm_instance=llm) + + with self.assertRaises(RuntimeError): + synth.generate_data_batch("CoT", ["患者男,58岁,突发胸痛,需要生成临床推理数据。"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/Dockerfile b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/Dockerfile index 76a0f760..85efb7fd 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/Dockerfile +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/Dockerfile @@ -3,16 +3,13 @@ FROM ${BASE_IMAGE} WORKDIR /app -COPY data_synthesis_service/requirements-base.txt /tmp/requirements-base.txt COPY data_synthesis_service/requirements.txt /tmp/requirements.txt -COPY data_synthesis_service/requirements-npu.txt /tmp/requirements-npu.txt -ARG REQUIREMENTS_FILE=requirements.txt -RUN python -m pip install --no-cache-dir --no-deps -r /tmp/${REQUIREMENTS_FILE} +RUN python -m pip install --no-cache-dir --no-deps -r /tmp/requirements.txt COPY data_synthesis /app/data_synthesis COPY data_synthesis_service /app/data_synthesis_service ENV PYTHONPATH=/app -EXPOSE 18080 +EXPOSE 18103 -CMD ["bash", "-lc", "set -e; unset ASCEND_LAUNCH_BLOCKING; export HCCL_OP_EXPANSION_MODE=AIV; source /usr/local/Ascend/ascend-toolkit/set_env.sh; exec python -m uvicorn data_synthesis_service.app:app --host 0.0.0.0 --port 18080"] +CMD ["bash", "-lc", "set -e; unset ASCEND_LAUNCH_BLOCKING; export HCCL_OP_EXPANSION_MODE=AIV; source /usr/local/Ascend/ascend-toolkit/set_env.sh; exec python -m uvicorn data_synthesis_service.app:app --host 0.0.0.0 --port ${DATA_SYNTHESIS_SERVICE_PORT:-18103}"] diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/README.md b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/README.md index 65d1f771..3814e77d 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/README.md +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/README.md @@ -1,51 +1,35 @@ # data_synthesis_service 独立服务 -本目录是数据合成独立 HTTP 服务源码。 +该目录是数据合成算子的独立 FastAPI 服务代码,只提供数据合成能力。 ## 接口 - `GET /health` - `POST /synthesize-file` -- `POST /evaluate-file` -## 本地启动示例 +## 启动 ```bash -python -m uvicorn data_synthesis_service.app:app --host 0.0.0.0 --port 18080 +python -m uvicorn data_synthesis_service.app:app --host 0.0.0.0 --port 18103 ``` -## 依赖 - -- `requirements.txt` 是独立服务生产依赖,完全对标 910b-jss 已验证镜像 `huizhi:test-v018`。 -- 基础镜像固定为 `quay.io/ascend/vllm-ascend:v0.18.0rc1`,对应 Python `3.11.14`、CANN `8.5.1`。 -- 关键版本包括 `vllm==0.18.0+empty`、`vllm_ascend==0.18.0rc1`、`torch==2.9.0+cpu`、`torch_npu==2.9.0.post1+gitee7ba04`。 -- `requirements-base.txt` 只用于无模型接口冒烟测试。 -- `requirements-npu.txt` 是兼容旧文档的别名,等价引用 `requirements.txt`。 -- DataMate 算子本体依赖在 `operator_src/requirements.txt`,不应安装 vLLM。 - -正式 NPU 构建示例: +正式容器建议使用 `data-synthesis-service` 作为容器名,并加入 DataMate 所在 Docker 网络。DataMate 算子默认访问: -```bash -docker build -t data-synthesis-service:latest \ - -f data_synthesis_service/Dockerfile . +```text +http://data-synthesis-service:18103 ``` -不传构建参数时默认使用 910b-jss 对标基础镜像并安装 `requirements.txt`。无模型接口冒烟测试可显式增加 `--build-arg REQUIREMENTS_FILE=requirements-base.txt`。 +## 依赖 -Dockerfile 使用 `pip install --no-deps`。这是为了保留 `quay.io/ascend/vllm-ascend:v0.18.0rc1` 中已经验证的 vLLM-Ascend 依赖闭包,避免 pip 重新解析传递依赖导致版本漂移。 +`requirements.txt` 对标已验证的 Ascend/vLLM 环境;DataMate 算子本体不安装 vLLM,只通过 HTTP 调用该独立服务。 ## 模型路径 -启动服务前通过环境变量指定容器内模型路径: +通过环境变量指定模型路径: -- `DATA_SYNTHESIS_MODEL_PATH` -- `DATA_EVALUATOR_MODEL_PATH` +- `DATA_SYNTHESIS_MODEL_PATH`:数据合成模型,默认值为 `/model/Qwen/Qwen3-4B-Instruct-2507`。 +容器内建议设置: -默认模型挂载点为容器内 `/model`。 - -路径说明: - -- `data_synthesis_service/` 与 `data_synthesis/` 是构建上下文中的相对源码目录。 -- `/model` 是服务容器内模型挂载点,不是主机固定路径;主机模型目录由 Docker `-v` 参数挂载。 -- `/tmp/requirements*.txt` 是 Dockerfile 构建阶段临时依赖文件路径。 -- `/usr/local/Ascend/...` 是 vLLM-Ascend 基础镜像和宿主机驱动的容器内标准路径;非标准镜像需要提供等价路径。 +```bash +export no_proxy="localhost,127.0.0.1,data-synthesis-service" +``` diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/app.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/app.py index b502c8ff..24163161 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/app.py +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/app.py @@ -1,3 +1,5 @@ +import os +from contextlib import asynccontextmanager from typing import List, Optional from fastapi import FastAPI, HTTPException @@ -14,22 +16,24 @@ class SynthesizeFileRequest(BaseModel): file_name: str = Field(..., min_length=1) text: str = Field(..., min_length=1) task_types: Optional[List[str]] = None - include_metrics: bool = True + include_metrics: bool = False -class EvaluateFileRequest(BaseModel): - file_name: str = Field(..., min_length=1) - text: str = Field(..., min_length=1) - target_dimensions: Optional[List[str]] = None - include_summary: bool = True - model_path: Optional[str] = None - backend: Optional[str] = None +def _skip_warmup() -> bool: + return str(os.environ.get("DATA_SYNTHESIS_SKIP_WARMUP", "")).strip().lower() in {"1", "true", "yes", "on"} def create_app(service: Optional[SynthesisService] = None) -> FastAPI: - app = FastAPI(title="data_synthesis_service", version="1.0.0") active_service = service or SynthesisService() + @asynccontextmanager + async def lifespan(_: FastAPI): + if not _skip_warmup(): + active_service.warmup() + yield + + app = FastAPI(title="data_synthesis_service", version="1.0.0", lifespan=lifespan) + @app.get("/health") def health_get() -> dict: return active_service.health() @@ -54,24 +58,6 @@ def synthesize_file(request: SynthesizeFileRequest) -> dict: except Exception as exc: raise HTTPException(status_code=500, detail=str(exc)) from exc - @app.post("/evaluate-file") - def evaluate_file(request: EvaluateFileRequest) -> dict: - try: - return active_service.evaluate_text( - file_name=request.file_name, - text=request.text, - target_dimensions=request.target_dimensions, - include_summary=request.include_summary, - model_path=request.model_path, - backend=request.backend, - ) - except ValueError as exc: - raise HTTPException(status_code=400, detail=str(exc)) from exc - except RuntimeError as exc: - raise HTTPException(status_code=503, detail=str(exc)) from exc - except Exception as exc: - raise HTTPException(status_code=500, detail=str(exc)) from exc - return app diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/core.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/core.py index 2ec510b1..5ddf3e98 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/core.py +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/core.py @@ -2,7 +2,9 @@ import os import subprocess import sys +import threading import time +from concurrent.futures import ThreadPoolExecutor from dataclasses import dataclass from typing import Any, Dict, Iterable, List, Optional @@ -13,14 +15,54 @@ if DATA_SYNTHESIS_DIR not in sys.path: sys.path.insert(0, DATA_SYNTHESIS_DIR) -from data_evaluator import MedicalDataEvaluator from data_synthesizer import MedicalDataSynthesizer -from requirement_metrics import calculate_generation_metrics, check_project_targets SUPPORTED_TASK_TYPES = ("QA", "CoT", "Preference") -DEFAULT_EVALUATION_DIMENSIONS = ("准确性", "相关性", "安全性", "多样性", "完整性") -DEFAULT_EVALUATOR_MODEL_PATH = "/model/Qwen/Qwen2.5-7B-Instruct" +DEFAULT_SYNTHESIS_MODEL_PATH = "/model/Qwen/Qwen3-4B-Instruct-2507" +SERVICE_REQUEST_LOCK = threading.RLock() +WORKER_RESULT_PREFIX = "__DATA_SYNTHESIS_RESULT__" + + +def _parse_worker_stdout(stdout: str) -> Dict[str, Any]: + output_lines = [line.strip() for line in stdout.splitlines() if line.strip()] + if not output_lines: + raise RuntimeError("subprocess returned empty output") + + for line in reversed(output_lines): + if line.startswith(WORKER_RESULT_PREFIX): + return json.loads(line[len(WORKER_RESULT_PREFIX):]) + + for line in reversed(output_lines): + if line.startswith("{") or line.startswith("["): + return json.loads(line) + + raise RuntimeError("subprocess returned no JSON result") + + +def _initialize_npu_context() -> Optional[str]: + visible = ( + os.environ.get("ASCEND_VISIBLE_DEVICES") + or os.environ.get("ASCEND_RT_VISIBLE_DEVICES") + or os.environ.get("NPU_VISIBLE_DEVICES") + or "" + ).strip() + logical_device = 0 + if visible: + first = visible.split(",")[0].strip() + if first.isdigit() and len(visible.split(",")) > 1: + logical_device = 0 + + try: + import torch + import torch_npu # noqa: F401 + + if hasattr(torch, "npu") and torch.npu.is_available(): + torch.npu.set_device(logical_device) + return f"npu:{logical_device}" + except Exception as exc: # pragma: no cover - depends on Ascend runtime + return f"npu_init_failed:{exc}" + return None @dataclass @@ -33,6 +75,18 @@ class _GeneratedResult: outputs: List[_GeneratedCandidate] +def _sampling_param_value(sampling_params: Any, name: str, default: Any, value_type: Any) -> Any: + kwargs = getattr(sampling_params, "kwargs", None) + if isinstance(kwargs, dict) and name in kwargs: + value = kwargs[name] + else: + value = getattr(sampling_params, name, default) + try: + return value_type(value) + except (TypeError, ValueError): + return default + + class TransformersLLMAdapter: def __init__(self, model_path: str) -> None: try: @@ -48,6 +102,7 @@ def __init__(self, model_path: str) -> None: import torch_npu # noqa: F401 if hasattr(torch, "npu") and torch.npu.is_available(): + _initialize_npu_context() self._device = "npu:0" model_dtype = torch.float16 except Exception: @@ -68,10 +123,10 @@ def __init__(self, model_path: str) -> None: self._model.eval() def generate(self, prompts: List[str], sampling_params: Any) -> List[_GeneratedResult]: - max_new_tokens = int(getattr(sampling_params, "kwargs", {}).get("max_tokens", 256)) - temperature = float(getattr(sampling_params, "kwargs", {}).get("temperature", 0.1)) - top_p = float(getattr(sampling_params, "kwargs", {}).get("top_p", 0.9)) - repetition_penalty = float(getattr(sampling_params, "kwargs", {}).get("repetition_penalty", 1.0)) + max_new_tokens = _sampling_param_value(sampling_params, "max_tokens", 256, int) + temperature = _sampling_param_value(sampling_params, "temperature", 0.1, float) + top_p = _sampling_param_value(sampling_params, "top_p", 0.9, float) + repetition_penalty = _sampling_param_value(sampling_params, "repetition_penalty", 1.0, float) outputs: List[_GeneratedResult] = [] for prompt in prompts: @@ -109,134 +164,38 @@ def _normalize_task_types(task_types: Optional[Iterable[str]]) -> List[str]: return normalized -def _normalize_dimensions(target_dimensions: Optional[Iterable[str]]) -> List[str]: - if target_dimensions is None: - return list(DEFAULT_EVALUATION_DIMENSIONS) - normalized = [str(dim).strip() for dim in target_dimensions if str(dim).strip()] - invalid = [dim for dim in normalized if dim not in DEFAULT_EVALUATION_DIMENSIONS] - if invalid: - raise ValueError(f"Unsupported target_dimensions: {invalid}") - if not normalized: - raise ValueError("target_dimensions must not be empty") - return normalized - - -def _make_record(record_id: int, task_type: str, payload: Dict[str, Any]) -> Dict[str, Any]: - return { - "id": record_id, - "type": task_type, - "content": json.dumps(payload, ensure_ascii=False), - } - - -def _records_from_synthesis_payload(payload: Dict[str, Any]) -> List[Dict[str, Any]]: - records: List[Dict[str, Any]] = [] - next_id = 1 - results = payload.get("results", {}) - if not isinstance(results, dict): - return records - - for task_type in SUPPORTED_TASK_TYPES: - items = results.get(task_type, []) - if not isinstance(items, list): - continue - for item in items: - data = item - if isinstance(item, dict) and "data" in item: - if item.get("status") != "success": - continue - data = item.get("data", {}) - if not isinstance(data, dict): - continue - records.append(_make_record(next_id, task_type, data)) - next_id += 1 - return records - - -def _parse_evaluation_input(text: str) -> List[Dict[str, Any]]: - raw = (text or "").strip() - if not raw: - raise ValueError("text must not be empty") - - try: - parsed = json.loads(raw) - except json.JSONDecodeError as exc: - raise ValueError("evaluation input must be JSON text") from exc - - if isinstance(parsed, dict) and "results" in parsed: - records = _records_from_synthesis_payload(parsed) - if records: - return records - raise ValueError("No successful generated records found in synthesis results") - - if isinstance(parsed, dict) and isinstance(parsed.get("records"), list): - parsed = parsed["records"] - - if isinstance(parsed, dict) and "content" in parsed: - parsed = [parsed] - - if not isinstance(parsed, list): - raise ValueError("evaluation input must be a JSON array, a record object, or synthesis results JSON") - - records: List[Dict[str, Any]] = [] - for idx, item in enumerate(parsed, start=1): - if not isinstance(item, dict): - raise ValueError("Each evaluation record must be a JSON object") - content = item.get("content") - if isinstance(content, dict): - task_type = str(item.get("type") or "QA") - records.append(_make_record(int(item.get("id") or idx), task_type, content)) - continue - if not isinstance(content, str) or not content.strip(): - raise ValueError("Each evaluation record must contain non-empty content") - records.append( - { - "id": int(item.get("id") or idx), - "type": str(item.get("type") or "QA"), - "content": content, - } - ) - - if not records: - raise ValueError("No evaluation records found") - return records - - class SynthesisService: def __init__( self, model_path: Optional[str] = None, - evaluator_model_path: Optional[str] = None, synthesizer: Any = None, - evaluator: Any = None, ) -> None: - self.model_path = model_path or os.environ.get("DATA_SYNTHESIS_MODEL_PATH") or os.environ.get("MODEL_PATH") - self.evaluator_model_path = ( - evaluator_model_path - or os.environ.get("DATA_EVALUATOR_MODEL_PATH") - or DEFAULT_EVALUATOR_MODEL_PATH + env_synthesis_model_path = (os.environ.get("DATA_SYNTHESIS_MODEL_PATH") or "").strip() + env_model_path = (os.environ.get("MODEL_PATH") or "").strip() + self.model_path = ( + (model_path or "").strip() + or env_synthesis_model_path + or env_model_path + or DEFAULT_SYNTHESIS_MODEL_PATH ) self.backend = os.environ.get("DATA_SYNTHESIS_BACKEND", "auto").lower() - self.run_mode = os.environ.get("DATA_SYNTHESIS_RUN_MODE", "inprocess").lower() + requested_run_mode = os.environ.get("DATA_SYNTHESIS_RUN_MODE", "inprocess").lower() + force_subprocess = os.environ.get("DATA_SYNTHESIS_FORCE_SUBPROCESS", "").lower() == "true" + self.run_mode = "subprocess" if requested_run_mode == "subprocess" and force_subprocess else "inprocess" self._ready = False - self._init_error: Optional[str] = "Service not initialized" + self._init_error: Optional[str] = None self._synthesizer_error: Optional[str] = None - self._evaluator_error: Optional[str] = None self.synthesizer = synthesizer - self.evaluator = evaluator - self.evaluator_backend = ( - os.environ.get("DATA_EVALUATOR_BACKEND") - or "vllm" - ).strip().lower() + self._model_lock = threading.RLock() + self._model_executor = ThreadPoolExecutor(max_workers=1, thread_name_prefix="data-synthesis-model") + self._npu_context: Optional[str] = None - def _initialize_components(self) -> None: - try: - self.synthesizer = self.synthesizer or self._build_synthesizer() - self._ready = True - self._init_error = None - except Exception as exc: - self._ready = False - self._init_error = str(exc) + def _run_on_model_thread(self, func: Any, *args: Any, **kwargs: Any) -> Any: + return self._model_executor.submit(func, *args, **kwargs).result() + + def _run_exclusive_request(self, func: Any, *args: Any, **kwargs: Any) -> Any: + with SERVICE_REQUEST_LOCK: + return func(*args, **kwargs) def _ensure_synthesizer_initialized(self) -> None: if self.synthesizer is not None: @@ -244,7 +203,7 @@ def _ensure_synthesizer_initialized(self) -> None: self._init_error = None return try: - self.synthesizer = self._build_synthesizer() + self.synthesizer = self._run_on_model_thread(self._build_synthesizer) self._ready = True self._init_error = None self._synthesizer_error = None @@ -253,39 +212,34 @@ def _ensure_synthesizer_initialized(self) -> None: self._init_error = str(exc) self._synthesizer_error = str(exc) - def _ensure_evaluator_initialized(self, backend: Optional[str] = None) -> None: - requested_backend = (backend or self.evaluator_backend or "vllm").strip().lower() - current_backend = getattr(self.evaluator, "backend", None) - if self.evaluator is not None and current_backend in (None, requested_backend): - self._evaluator_error = None - return - try: - self.evaluator = MedicalDataEvaluator( - self.evaluator_model_path, - backend=requested_backend, - ) - self._evaluator_error = None - except Exception as exc: - self._evaluator_error = str(exc) - raise - def _ensure_initialized(self) -> None: - if self._ready and self.synthesizer is not None: - return - self._ensure_synthesizer_initialized() - if not self._ready: + with self._model_lock: + if self._ready and self.synthesizer is not None: + return self._ensure_synthesizer_initialized() + if not self._ready: + self._ensure_synthesizer_initialized() + + def warmup(self) -> Dict[str, Any]: + if self.run_mode == "subprocess": + return self.health() + self._ensure_initialized() + if not self._ready or self.synthesizer is None: + return self.health() + with self._model_lock: + self._run_on_model_thread( + self.synthesizer.generate_data_batch, + "QA", + ["warmup probe"], + ) + return self.health() def health(self) -> Dict[str, Any]: - if self.run_mode != "subprocess": - self._ensure_initialized() return { "service": "data_synthesis", "ready": True if self.run_mode == "subprocess" else self._ready, "model_path": self.model_path, - "evaluator_model_path": self.evaluator_model_path, "backend": self.backend, - "evaluator_backend": self.evaluator_backend, "error": None if self.run_mode == "subprocess" else self._init_error, } @@ -318,7 +272,8 @@ def synthesize_text( include_metrics: bool = True, ) -> Dict[str, Any]: if self.run_mode == "subprocess": - return self._synthesize_via_subprocess( + return self._run_exclusive_request( + self._synthesize_via_subprocess, file_name=file_name, text=text, task_types=task_types, @@ -336,34 +291,32 @@ def synthesize_text( normalized_task_types = _normalize_task_types(task_types) results: Dict[str, List[Dict[str, Any]]] = {task_type: [] for task_type in SUPPORTED_TASK_TYPES} records: List[Dict[str, Any]] = [] - evaluation_inputs: List[Dict[str, Any]] = [] for task_type in normalized_task_types: started_at = time.time() - batch_results = self.synthesizer.generate_data_batch(task_type, [normalized_text]) + with self._model_lock: + batch_results = self._run_on_model_thread( + self.synthesizer.generate_data_batch, + task_type, + [normalized_text], + ) elapsed = time.time() - started_at per_item_latency = elapsed / max(len(batch_results), 1) results[task_type] = batch_results for item in batch_results: - record = { - "task_type": task_type, - "status": item.get("status", "failed"), - "latency": per_item_latency, - "data": item.get("data", {}), - } - records.append(record) - if item.get("status") == "success": - evaluation_inputs.append( - { - "type": task_type, - "content": json.dumps(item.get("data", {}), ensure_ascii=False), - } - ) + records.append( + { + "task_type": task_type, + "status": item.get("status", "failed"), + "latency": per_item_latency, + "data": item.get("data", {}), + } + ) metrics: Dict[str, Any] = {} if include_metrics: - metrics = self._build_metrics(records, evaluation_inputs) + metrics = self._build_metrics(records) return { "source_file": file_name, @@ -373,59 +326,6 @@ def synthesize_text( "status": "success", } - def evaluate_text( - self, - file_name: str, - text: str, - target_dimensions: Optional[Iterable[str]] = None, - include_summary: bool = True, - model_path: Optional[str] = None, - backend: Optional[str] = None, - ) -> Dict[str, Any]: - if self.run_mode == "subprocess": - return self._evaluate_via_subprocess( - file_name=file_name, - text=text, - target_dimensions=target_dimensions, - include_summary=include_summary, - model_path=model_path, - backend=backend, - ) - - if model_path and model_path != self.evaluator_model_path: - self.evaluator_model_path = model_path - self.evaluator = None - try: - self._ensure_evaluator_initialized(backend or self.evaluator_backend or "vllm") - except Exception as exc: - raise RuntimeError(str(exc)) from exc - if self.evaluator is None: - raise RuntimeError(self._init_error or "Evaluator is not ready") - - records = _parse_evaluation_input(text) - dimensions = _normalize_dimensions(target_dimensions) - evaluation_results = self.evaluator.evaluate(records, target_dimensions=dimensions) - - response: Dict[str, Any] = { - "source_file": file_name, - "record_count": len(records), - "dimensions": dimensions, - "results": evaluation_results, - "runtime": ( - self.evaluator.runtime_metadata() - if hasattr(self.evaluator, "runtime_metadata") - else { - "evaluator_backend": getattr(self.evaluator, "backend", "unknown"), - "evaluator_model_path": self.evaluator_model_path, - "vllm_enabled": getattr(self.evaluator, "backend", None) == "vllm", - } - ), - "status": "success", - } - if include_summary: - response["summary"] = self._build_evaluation_summary(records, evaluation_results, dimensions) - return response - def _synthesize_via_subprocess( self, file_name: str, @@ -457,7 +357,7 @@ def _synthesize_via_subprocess( task_types=payload["task_types"], include_metrics=payload["include_metrics"], ) -print(json.dumps(result, ensure_ascii=False)) +print("__DATA_SYNTHESIS_RESULT__" + json.dumps(result, ensure_ascii=False)) """ env = os.environ.copy() env["DATA_SYNTHESIS_RUN_MODE"] = "inprocess" @@ -473,135 +373,23 @@ def _synthesize_via_subprocess( if completed.returncode != 0: error_text = (completed.stderr or completed.stdout or "subprocess failed").strip() raise RuntimeError(error_text) - output_lines = [line.strip() for line in completed.stdout.splitlines() if line.strip()] - if not output_lines: - raise RuntimeError("subprocess returned empty output") - return json.loads(output_lines[-1]) - - def _evaluate_via_subprocess( - self, - file_name: str, - text: str, - target_dimensions: Optional[Iterable[str]], - include_summary: bool, - model_path: Optional[str], - backend: Optional[str] = None, - ) -> Dict[str, Any]: - normalized_dimensions = _normalize_dimensions(target_dimensions) - worker_payload = { - "action": "evaluate", - "file_name": file_name, - "text": text, - "target_dimensions": normalized_dimensions, - "include_summary": include_summary, - "model_path": model_path or self.evaluator_model_path, - "synthesis_model_path": self.model_path, - "backend": self.backend, - "evaluator_backend": backend or self.evaluator_backend or "vllm", - } - return self._run_subprocess_worker(worker_payload) - - def _run_subprocess_worker(self, worker_payload: Dict[str, Any]) -> Dict[str, Any]: - worker_code = """ -import json -import os -import sys -payload = json.loads(sys.stdin.read()) -os.environ["DATA_SYNTHESIS_MODEL_PATH"] = payload.get("synthesis_model_path") or payload.get("model_path") or "" -os.environ["DATA_EVALUATOR_MODEL_PATH"] = payload.get("model_path") or "" -os.environ["DATA_SYNTHESIS_BACKEND"] = payload.get("backend") or "auto" -os.environ["DATA_EVALUATOR_BACKEND"] = payload.get("evaluator_backend") or "vllm" -from data_synthesis_service.core import SynthesisService -service = SynthesisService( - model_path=payload.get("synthesis_model_path"), - evaluator_model_path=payload.get("model_path"), -) -action = payload.get("action") -if action == "synthesize": - result = service.synthesize_text( - file_name=payload["file_name"], - text=payload["text"], - task_types=payload["task_types"], - include_metrics=payload["include_metrics"], - ) -elif action == "evaluate": - result = service.evaluate_text( - file_name=payload["file_name"], - text=payload["text"], - target_dimensions=payload["target_dimensions"], - include_summary=payload["include_summary"], - model_path=payload.get("model_path"), - backend=payload.get("evaluator_backend"), - ) -else: - raise RuntimeError(f"Unsupported action: {action}") -print(json.dumps(result, ensure_ascii=False)) -""" - env = os.environ.copy() - env["DATA_SYNTHESIS_RUN_MODE"] = "inprocess" - completed = subprocess.run( - [sys.executable, "-c", worker_code], - input=json.dumps(worker_payload, ensure_ascii=False), - text=True, - capture_output=True, - env=env, - cwd=PROJECT_ROOT, - check=False, + return _parse_worker_stdout(completed.stdout) + + def _build_metrics(self, records: List[Dict[str, Any]]) -> Dict[str, Any]: + success_count = sum(1 for record in records if record.get("status") == "success") + total = len(records) + avg_latency = ( + sum(float(record.get("latency", 0.0)) for record in records) / total + if total + else 0.0 ) - if completed.returncode != 0: - error_text = (completed.stderr or completed.stdout or "subprocess failed").strip() - raise RuntimeError(error_text) - output_lines = [line.strip() for line in completed.stdout.splitlines() if line.strip()] - if not output_lines: - raise RuntimeError("subprocess returned empty output") - return json.loads(output_lines[-1]) - - def _build_metrics( - self, - records: List[Dict[str, Any]], - evaluation_inputs: List[Dict[str, Any]], - ) -> Dict[str, Any]: - try: - self._ensure_evaluator_initialized("rule") - evaluator_scores = self.evaluator.evaluate(evaluation_inputs) if evaluation_inputs else [] - summary = calculate_generation_metrics(records, evaluator_scores) - return { - "ready": True, - "summary": summary, - "targets": check_project_targets(summary), - } - except Exception as exc: - return {"ready": False, "error": str(exc)} - - def _build_evaluation_summary( - self, - records: List[Dict[str, Any]], - evaluation_results: List[Dict[str, Any]], - dimensions: List[str], - ) -> Dict[str, Any]: - per_dimension: Dict[str, Dict[str, Any]] = {} - for dim in dimensions: - scores = [] - for item in evaluation_results: - score = item.get("scores", {}).get(dim, {}).get("score", -1) - if isinstance(score, int) and score >= 0: - scores.append(score) - pass_count = sum(1 for score in scores if score == 1) - total = len(scores) - pass_rate = (pass_count / total * 100.0) if total else 0.0 - per_dimension[dim] = { - "pass_count": pass_count, - "total": total, - "pass_rate_pct": pass_rate, - } - - task_type_counts: Dict[str, int] = {} - for record in records: - task_type = str(record.get("type") or "QA") - task_type_counts[task_type] = task_type_counts.get(task_type, 0) + 1 - return { - "record_count": len(records), - "task_type_counts": task_type_counts, - "dimensions": per_dimension, + "ready": True, + "summary": { + "record_count": total, + "success_count": success_count, + "success_rate_pct": (success_count / total * 100.0) if total else 0.0, + "avg_latency_sec": avg_latency, + }, + "note": "Model-based quality evaluation is provided by data_quality_evaluator_service.", } diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements-base.txt b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements-base.txt deleted file mode 100644 index 29ad47ad..00000000 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements-base.txt +++ /dev/null @@ -1,7 +0,0 @@ -# HTTP service base dependencies for smoke tests without model inference. -# Versions are aligned with 910b-jss huizhi:test-v018. -fastapi==0.123.10 -uvicorn==0.42.0 -pydantic==2.12.5 -Jinja2==3.1.6 -requests==2.33.1 diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements-npu.txt b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements-npu.txt deleted file mode 100644 index 626e52fe..00000000 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements-npu.txt +++ /dev/null @@ -1,2 +0,0 @@ -# Backward-compatible alias for the full NPU/vLLM service dependencies. --r requirements.txt diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements.txt b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements.txt index b65dd8c1..bf14eb8f 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements.txt +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/requirements.txt @@ -1,20 +1,24 @@ -# Independent service production dependencies aligned with 910b-jss huizhi:test-v018. -# Base image: quay.io/ascend/vllm-ascend:v0.18.0rc1 -# Python: 3.11.14, CANN: 8.5.1 -# Do not put these into the DataMate operator_src/requirements.txt. -fastapi==0.123.10 -uvicorn==0.42.0 -pydantic==2.12.5 -Jinja2==3.1.6 -requests==2.33.1 -vllm==0.18.0+empty -vllm_ascend==0.18.0rc1 -torch==2.9.0+cpu -torch_npu==2.9.0.post1+gitee7ba04 -transformers==4.57.6 -tokenizers==0.22.2 +# Independent service production dependencies verified in the 910b +# data-synthesis-service container (my_npu_env:v1, Python 3.10.16). +# Do not put these heavy model dependencies into operator_src/requirements.txt. +fastapi==0.136.3 +uvicorn==0.49.0 +pydantic==2.10.6 +Jinja2==3.1.5 +requests==2.32.5 +torch==2.1.0 +torch-npu==2.1.0 +transformers==4.52.4 +tokenizers==0.21.4 sentencepiece==0.2.1 einops==0.8.2 numpy==1.26.4 safetensors==0.7.0 -typing_extensions==4.15.0 +modelscope==1.34.0 +pandas==2.2.3 +matplotlib==3.10.0 + +# Optional backend for vLLM mode. The default verified service path uses the +# Transformers backend; if DATA_SYNTHESIS_BACKEND=vllm is enabled, use: +# vllm==0.13.0+empty +# vllm-ascend==0.13.0 diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_app.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_app.py index d4935cb8..fbd8e6d2 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_app.py +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_app.py @@ -14,10 +14,19 @@ class _FakeService: + def __init__(self): + self.last_include_metrics = None + self.warmup_calls = 0 + def health(self): return {"ready": True, "model_path": "/models/demo", "service": "data_synthesis"} + def warmup(self): + self.warmup_calls += 1 + return self.health() + def synthesize_text(self, file_name, text, task_types=None, include_metrics=True): + self.last_include_metrics = include_metrics return { "source_file": file_name, "task_types": task_types or ["QA", "CoT", "Preference"], @@ -26,27 +35,28 @@ def synthesize_text(self, file_name, text, task_types=None, include_metrics=True "status": "success", } - def evaluate_text( - self, - file_name, - text, - target_dimensions=None, - include_summary=True, - model_path=None, - backend=None, - ): - return { - "source_file": file_name, - "record_count": 1, - "dimensions": target_dimensions or ["准确性", "相关性", "安全性", "多样性", "完整性"], - "results": [{"id": 1, "scores": {"准确性": {"score": 1, "reason": "ok"}}}], - "summary": {"record_count": 1} if include_summary else None, - "model_path": model_path, - "status": "success", - } - class AppTests(unittest.TestCase): + def test_app_warmup_runs_on_startup(self): + fake_service = _FakeService() + with TestClient(create_app(service=fake_service)): + pass + self.assertEqual(fake_service.warmup_calls, 1) + + def test_app_can_skip_warmup_via_env(self): + fake_service = _FakeService() + original = os.environ.get("DATA_SYNTHESIS_SKIP_WARMUP") + os.environ["DATA_SYNTHESIS_SKIP_WARMUP"] = "true" + try: + with TestClient(create_app(service=fake_service)): + pass + finally: + if original is None: + os.environ.pop("DATA_SYNTHESIS_SKIP_WARMUP", None) + else: + os.environ["DATA_SYNTHESIS_SKIP_WARMUP"] = original + self.assertEqual(fake_service.warmup_calls, 0) + def test_health_endpoint(self): client = TestClient(create_app(service=_FakeService())) response = client.post("/health", json={}) @@ -60,7 +70,8 @@ def test_health_endpoint_supports_get(self): self.assertTrue(response.json()["ready"]) def test_synthesize_endpoint(self): - client = TestClient(create_app(service=_FakeService())) + fake_service = _FakeService() + client = TestClient(create_app(service=fake_service)) response = client.post( "/synthesize-file", json={"file_name": "demo.txt", "text": "abc"}, @@ -69,28 +80,12 @@ def test_synthesize_endpoint(self): payload = response.json() self.assertEqual(payload["source_file"], "demo.txt") self.assertEqual(payload["status"], "success") + self.assertEqual(fake_service.last_include_metrics, False) - def test_evaluate_endpoint(self): + def test_evaluate_endpoint_is_not_exposed_by_synthesis_service(self): client = TestClient(create_app(service=_FakeService())) response = client.post( "/evaluate-file", json={"file_name": "demo.json", "text": '{"content":"{}"}'}, ) - self.assertEqual(response.status_code, 200) - payload = response.json() - self.assertEqual(payload["source_file"], "demo.json") - self.assertEqual(payload["status"], "success") - - def test_evaluate_endpoint_accepts_dedicated_model_path(self): - client = TestClient(create_app(service=_FakeService())) - response = client.post( - "/evaluate-file", - json={ - "file_name": "demo.json", - "text": '{"content":"{}"}', - "model_path": "/model/Qwen/Qwen2.5-7B-Instruct", - }, - ) - self.assertEqual(response.status_code, 200) - payload = response.json() - self.assertEqual(payload["model_path"], "/model/Qwen/Qwen2.5-7B-Instruct") + self.assertEqual(response.status_code, 404) diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_evaluator_backend_service.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_evaluator_backend_service.py index a8beae25..096c21e9 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_evaluator_backend_service.py +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_evaluator_backend_service.py @@ -2,6 +2,7 @@ import os import sys import unittest +from subprocess import CompletedProcess from unittest.mock import patch @@ -44,8 +45,15 @@ def runtime_metadata(self): class EvaluatorBackendServiceTests(unittest.TestCase): + @patch("data_synthesis_service.core.subprocess.run") @patch("data_synthesis_service.core.MedicalDataEvaluator") - def test_evaluate_file_initializes_evaluator_with_vllm_backend(self, evaluator_cls): + def test_evaluate_file_routes_vllm_backend_to_isolated_worker(self, evaluator_cls, run_mock): + run_mock.return_value = CompletedProcess( + args=["python"], + returncode=0, + stdout='{"status":"success","source_file":"records.json","record_count":1,"dimensions":[],"results":[],"runtime":{"evaluator_backend":"vllm","vllm_enabled":true}}', + stderr="", + ) evaluator_cls.side_effect = lambda model_path, **kwargs: _FakeEvaluator(kwargs["backend"]) service = SynthesisService(synthesizer=_FakeSynthesizer()) @@ -54,7 +62,8 @@ def test_evaluate_file_initializes_evaluator_with_vllm_backend(self, evaluator_c json.dumps([{"id": 1, "type": "QA", "content": json.dumps({"question": "q", "answer": "a"})}]), ) - self.assertEqual(evaluator_cls.call_args.kwargs["backend"], "vllm") + evaluator_cls.assert_not_called() + run_mock.assert_called_once() self.assertEqual(result["runtime"]["evaluator_backend"], "vllm") self.assertTrue(result["runtime"]["vllm_enabled"]) diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_operator_process.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_operator_process.py index 36fb4dbe..805afbf8 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_operator_process.py +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_operator_process.py @@ -1,9 +1,9 @@ -import json import importlib.util +import json import os import sys import unittest -from unittest.mock import Mock +from unittest.mock import patch CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -15,23 +15,9 @@ def _load_operator_module(): candidate_paths = [ - os.path.join( - WORK_ROOT, - "submit", - "data_synthesis_delivery", - "operator_src", - "process.py", - ), - os.path.join( - os.path.dirname(PROJECT_ROOT), - "operator_src", - "process.py", - ), - os.path.join( - os.path.dirname(os.path.dirname(PROJECT_ROOT)), - "operator_src", - "process.py", - ), + os.path.join(WORK_ROOT, "submit", "data_synthesis_delivery", "operator_src", "process.py"), + os.path.join(os.path.dirname(PROJECT_ROOT), "operator_src", "process.py"), + os.path.join(os.path.dirname(os.path.dirname(PROJECT_ROOT)), "operator_src", "process.py"), ] process_path = next((path for path in candidate_paths if os.path.isfile(path)), candidate_paths[0]) spec = importlib.util.spec_from_file_location("data_synthesis_operator_process", process_path) @@ -48,6 +34,17 @@ def _load_operator_module(): class OperatorHelperTests(unittest.TestCase): + def test_mapper_defaults_to_hot_service_container(self): + mapper = DataSynthesisMapper() + self.assertEqual(mapper.service_url, "http://data-synthesis-service:18103") + + def test_mapper_rotates_across_service_url_pool(self): + mapper = DataSynthesisMapper(serviceUrls="http://svc-a:18103,http://svc-b:18104") + self.assertEqual(mapper.service_url, "http://svc-a:18103") + self.assertEqual(mapper._next_service_url(), "http://svc-a:18103") + self.assertEqual(mapper._next_service_url(), "http://svc-b:18104") + self.assertEqual(mapper._next_service_url(), "http://svc-a:18103") + def test_build_service_payload_prefers_sample_text(self): sample = {"fileName": "demo.txt", "text": "hello"} payload = build_service_payload(sample, ["QA"], True) @@ -63,4 +60,79 @@ def test_serialize_service_response_returns_json_text(self): def test_mapper_uses_higher_default_timeout_for_full_task_types(self): mapper = DataSynthesisMapper() - self.assertEqual(mapper.timeout_sec, 300) + self.assertEqual(mapper.timeout_sec, 3600) + + def test_mapper_uses_batch_safe_lock_wait(self): + mapper = DataSynthesisMapper() + self.assertEqual(mapper.lock_wait_timeout_sec, 7200) + + def test_mapper_clamps_stale_platform_lock_wait(self): + mapper = DataSynthesisMapper(lockWaitTimeoutSec=300) + self.assertEqual(mapper.lock_wait_timeout_sec, 7200) + + def test_mapper_upgrades_stale_platform_service_url(self): + mapper = DataSynthesisMapper(serviceUrl="http://data-synthesis-service:18080") + self.assertEqual(mapper.service_url, "http://data-synthesis-service:18103") + + def test_mapper_clamps_stale_platform_timeout(self): + mapper = DataSynthesisMapper(timeoutSec=300) + self.assertEqual(mapper.timeout_sec, 3600) + + def test_mapper_uses_service_specific_lock_path(self): + mapper = DataSynthesisMapper() + self.assertIn("18103", mapper.lock_path) + self.assertNotEqual(mapper.lock_path, operator_process.DEFAULT_LOCK_PATH) + self.assertFalse(mapper.use_service_lock) + + def test_mapper_disables_metrics_by_default_for_platform_batch(self): + mapper = DataSynthesisMapper() + sample = {"fileName": "demo.txt", "text": "sample text"} + + with patch.object(operator_process.requests, "post") as post: + post.return_value.status_code = 200 + post.return_value.json.return_value = {"status": "success", "results": {"QA": []}} + mapper.execute(sample) + + self.assertEqual(post.call_args.kwargs["json"]["include_metrics"], False) + + def test_mapper_uses_file_lock_for_service_call_when_explicitly_enabled(self): + mapper = DataSynthesisMapper(useServiceLock=True) + sample = {"fileName": "demo.txt", "text": "sample text"} + + with patch.object(operator_process, "service_call_lock") as lock_factory, patch.object(operator_process.requests, "post") as post: + lock = lock_factory.return_value + lock.__enter__.return_value = None + lock.__exit__.return_value = None + post.return_value.status_code = 200 + post.return_value.json.return_value = {"status": "success", "results": {"QA": []}} + mapper.execute(sample) + + lock_factory.assert_called_once_with(lock_path=mapper.lock_path, max_wait_sec=7200) + lock.__enter__.assert_called_once() + lock.__exit__.assert_called_once() + + def test_mapper_does_not_use_file_lock_by_default(self): + mapper = DataSynthesisMapper() + sample = {"fileName": "demo.txt", "text": "sample text"} + + with patch.object(operator_process, "service_call_lock") as lock_factory, patch.object(operator_process.requests, "post") as post: + post.return_value.status_code = 200 + post.return_value.json.return_value = {"status": "success", "results": {"QA": []}} + mapper.execute(sample) + + lock_factory.assert_not_called() + + def test_mapper_can_disable_file_lock_explicitly(self): + mapper = DataSynthesisMapper(useServiceLock=False) + sample = {"fileName": "demo.txt", "text": "sample text"} + + with patch.object(operator_process, "service_call_lock") as lock_factory, patch.object(operator_process.requests, "post") as post: + post.return_value.status_code = 200 + post.return_value.json.return_value = {"status": "success", "results": {"QA": []}} + mapper.execute(sample) + + lock_factory.assert_not_called() + + +if __name__ == "__main__": + unittest.main() diff --git a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_service_core.py b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_service_core.py index 95761123..13785c91 100644 --- a/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_service_core.py +++ b/runtime/ops/mapper/data_synthesis/service_patch/data_synthesis_service/tests/test_service_core.py @@ -1,7 +1,9 @@ -import json import os import sys +import threading +import time import unittest +from concurrent.futures import ThreadPoolExecutor from subprocess import CompletedProcess from unittest.mock import patch @@ -11,6 +13,7 @@ if PROJECT_ROOT not in sys.path: sys.path.insert(0, PROJECT_ROOT) +from data_synthesis_service import core as service_core from data_synthesis_service.core import SynthesisService @@ -38,22 +41,6 @@ def generate_data_batch(self, task_type, inputs): ] -class _FakeEvaluator: - def evaluate(self, data_list, target_dimensions=None): - return [ - { - "scores": { - "准确性": {"score": 1}, - "相关性": {"score": 1}, - "安全性": {"score": 1}, - "多样性": {"score": 1}, - "完整性": {"score": 1}, - } - } - for _ in data_list - ] - - class _FlakySynthesizer: def __init__(self): self.calls = 0 @@ -77,15 +64,6 @@ def generate_data_batch(self, task_type, inputs): }, } ] - if task_type == "CoT": - return [ - { - "status": "failed", - "reason": "repair_failed", - "raw_output": "meta reasoning noisy output", - "repair_raw_output": "meta reasoning noisy output", - } - ] return [ { "status": "failed", @@ -96,12 +74,80 @@ def generate_data_batch(self, task_type, inputs): ] +class _ConcurrencyTrackingSynthesizer: + def __init__(self): + self.active = 0 + self.max_active = 0 + self.lock = threading.Lock() + self.first_entered = threading.Event() + + def generate_data_batch(self, task_type, inputs): + with self.lock: + self.active += 1 + self.max_active = max(self.max_active, self.active) + self.first_entered.set() + time.sleep(0.1) + with self.lock: + self.active -= 1 + return [ + { + "status": "success", + "data": { + "question": f"{task_type}:{inputs[0]}", + "answer": "ok。", + }, + } + ] + + +class _ThreadAffinitySynthesizer: + def __init__(self): + self.init_thread_id = threading.get_ident() + + def generate_data_batch(self, task_type, inputs): + if threading.get_ident() != self.init_thread_id: + raise RuntimeError("model used from a different thread") + return [ + { + "status": "success", + "data": { + "question": f"{task_type}:{inputs[0]}", + "answer": "ok。", + }, + } + ] + + +class _WarmupTrackingSynthesizer: + def __init__(self): + self.calls = [] + + def generate_data_batch(self, task_type, inputs): + self.calls.append((task_type, list(inputs))) + return [ + { + "status": "success", + "data": { + "question": f"{task_type}:{inputs[0]}", + "answer": "ok", + }, + } + ] + + class ServiceCoreTests(unittest.TestCase): + def test_sampling_param_reader_supports_real_vllm_attributes(self): + class Params: + max_tokens = 1800 + temperature = 0.0 + top_p = 1.0 + repetition_penalty = 1.05 + + self.assertEqual(service_core._sampling_param_value(Params(), "max_tokens", 256, int), 1800) + self.assertEqual(service_core._sampling_param_value(Params(), "temperature", 0.1, float), 0.0) + def test_synthesize_text_returns_all_task_groups(self): - service = SynthesisService( - synthesizer=_FakeSynthesizer(), - evaluator=_FakeEvaluator(), - ) + service = SynthesisService(synthesizer=_FakeSynthesizer()) result = service.synthesize_text("case.txt", "patient text") self.assertEqual(result["status"], "success") self.assertEqual(result["source_file"], "case.txt") @@ -112,40 +158,39 @@ def test_synthesize_text_returns_all_task_groups(self): self.assertIn("metrics", result) def test_invalid_task_type_raises(self): - service = SynthesisService( - synthesizer=_FakeSynthesizer(), - evaluator=_FakeEvaluator(), - ) + service = SynthesisService(synthesizer=_FakeSynthesizer()) with self.assertRaises(ValueError): service.synthesize_text("case.txt", "patient text", task_types=["BAD"]) def test_empty_text_raises(self): - service = SynthesisService( - synthesizer=_FakeSynthesizer(), - evaluator=_FakeEvaluator(), - ) + service = SynthesisService(synthesizer=_FakeSynthesizer()) with self.assertRaises(ValueError): service.synthesize_text("case.txt", " ") - @patch("data_synthesis_service.core.MedicalDataEvaluator") @patch("data_synthesis_service.core.MedicalDataSynthesizer") - def test_service_can_initialize_with_cpu_fallback(self, synthesizer_cls, evaluator_cls): + def test_service_can_initialize_with_cpu_fallback(self, synthesizer_cls): synthesizer_cls.return_value = _FakeSynthesizer() - evaluator_cls.return_value = _FakeEvaluator() with patch.dict(os.environ, {"DATA_SYNTHESIS_MODEL_PATH": "/models/demo"}, clear=False): service = SynthesisService() + self.assertFalse(service.health()["ready"]) + self.assertEqual(service.synthesize_text("case.txt", "patient text")["status"], "success") self.assertTrue(service.health()["ready"]) - self.assertEqual(service.evaluator_model_path, "/model/Qwen/Qwen2.5-7B-Instruct") - def test_health_retries_initialization_after_transient_failure(self): + def test_constructor_does_not_initialize_npu_before_transformers_backend(self): + with patch("data_synthesis_service.core._initialize_npu_context") as init_mock: + service = SynthesisService(synthesizer=_FakeSynthesizer()) + self.assertIsNotNone(service) + init_mock.assert_not_called() + + def test_health_does_not_initialize_model(self): builder = _FlakySynthesizer() with patch.object(SynthesisService, "_build_synthesizer", side_effect=builder): - with patch("data_synthesis_service.core.MedicalDataEvaluator", return_value=_FakeEvaluator()): - with patch.dict(os.environ, {"DATA_SYNTHESIS_MODEL_PATH": "/models/demo"}, clear=False): - service = SynthesisService() - first = service.health() - self.assertTrue(first["ready"]) - self.assertIsNone(first["error"]) + with patch.dict(os.environ, {"DATA_SYNTHESIS_MODEL_PATH": "/models/demo"}, clear=False): + service = SynthesisService() + first = service.health() + self.assertFalse(first["ready"]) + self.assertIsNone(first["error"]) + self.assertEqual(builder.calls, 0) @patch("data_synthesis_service.core.subprocess.run") def test_subprocess_mode_uses_worker_process(self, run_mock): @@ -160,6 +205,7 @@ def test_subprocess_mode_uses_worker_process(self, run_mock): { "DATA_SYNTHESIS_MODEL_PATH": "/models/demo", "DATA_SYNTHESIS_RUN_MODE": "subprocess", + "DATA_SYNTHESIS_FORCE_SUBPROCESS": "true", }, clear=False, ): @@ -168,61 +214,20 @@ def test_subprocess_mode_uses_worker_process(self, run_mock): self.assertEqual(result["status"], "success") self.assertEqual(result["source_file"], "case.txt") - def test_evaluate_text_supports_synthesis_payload(self): - service = SynthesisService( - synthesizer=_FakeSynthesizer(), - evaluator=_FakeEvaluator(), - ) - text = """ -{ - "results": { - "QA": [ - { - "status": "success", - "data": { - "question": "q", - "answer": "a。" - } - } - ], - "CoT": [], - "Preference": [] - } -} -""" - result = service.evaluate_text("generated.json", text) - self.assertEqual(result["status"], "success") - self.assertEqual(result["record_count"], 1) - self.assertEqual(result["summary"]["record_count"], 1) - - @patch("data_synthesis_service.core.subprocess.run") - def test_evaluate_subprocess_uses_dedicated_evaluator_model_path(self, run_mock): - run_mock.return_value = CompletedProcess( - args=["python"], - returncode=0, - stdout='{"status":"success","source_file":"generated.json","record_count":1,"dimensions":["准确性"],"results":[],"summary":{"record_count":1}}', - stderr="", - ) + def test_default_synthesis_model_path_switches_to_qwen3_4b_instruct_2507(self): with patch.dict( os.environ, { - "DATA_SYNTHESIS_MODEL_PATH": "/model/Qwen/Qwen3-1___7b-Medical-R1-sft", - "DATA_EVALUATOR_MODEL_PATH": "/model/Qwen/Qwen2.5-7B-Instruct", - "DATA_SYNTHESIS_RUN_MODE": "subprocess", + "DATA_SYNTHESIS_MODEL_PATH": "", + "MODEL_PATH": "", }, clear=False, ): service = SynthesisService() - service.evaluate_text("generated.json", '[{"id":1,"type":"QA","content":"{\\"question\\":\\"q\\"}"}]') - - worker_payload = json.loads(run_mock.call_args.kwargs["input"]) - self.assertEqual(worker_payload["model_path"], "/model/Qwen/Qwen2.5-7B-Instruct") + self.assertEqual(service.model_path, "/model/Qwen/Qwen3-4B-Instruct-2507") def test_synthesize_text_does_not_apply_service_level_deterministic_fallback(self): - service = SynthesisService( - synthesizer=_PubMedUnstableSynthesizer(), - evaluator=_FakeEvaluator(), - ) + service = SynthesisService(synthesizer=_PubMedUnstableSynthesizer()) text = ( "Source style: PubMedQA (biomedical research QA)\n\n" "Research question: Can home blood pressure telemonitoring improve blood pressure " @@ -242,6 +247,127 @@ def test_synthesize_text_does_not_apply_service_level_deterministic_fallback(sel self.assertNotIn("service_fallback", result["results"]["Preference"][0]) self.assertNotIn("deterministic", result["results"]["Preference"][0]) + def test_synthesize_text_serializes_shared_model_requests(self): + synthesizer = _ConcurrencyTrackingSynthesizer() + service = SynthesisService(synthesizer=synthesizer) + + with ThreadPoolExecutor(max_workers=2) as executor: + first = executor.submit( + service.synthesize_text, + "case-1.txt", + "患者出现头晕。", + task_types=["QA"], + include_metrics=False, + ) + self.assertTrue(synthesizer.first_entered.wait(timeout=1)) + second = executor.submit( + service.synthesize_text, + "case-2.txt", + "患者出现咳嗽。", + task_types=["QA"], + include_metrics=False, + ) + self.assertEqual(first.result()["status"], "success") + self.assertEqual(second.result()["status"], "success") + + self.assertEqual(synthesizer.max_active, 1) + + def test_warmup_initializes_model_and_runs_qa_probe(self): + synthesizer = _WarmupTrackingSynthesizer() + service = SynthesisService(synthesizer=synthesizer) + + warmed = service.warmup() + + self.assertTrue(warmed["ready"]) + self.assertEqual(synthesizer.calls[0][0], "QA") + self.assertTrue(synthesizer.calls[0][1][0]) + + @patch("data_synthesis_service.core.subprocess.run") + def test_subprocess_mode_serializes_service_requests(self, run_mock): + active = 0 + max_active = 0 + lock = threading.Lock() + + def slow_subprocess(*args, **kwargs): + nonlocal active, max_active + with lock: + active += 1 + max_active = max(max_active, active) + time.sleep(0.1) + with lock: + active -= 1 + return CompletedProcess( + args=["python"], + returncode=0, + stdout='{"status":"success","source_file":"case.txt","task_types":["QA"],"results":{"QA":[],"CoT":[],"Preference":[]},"metrics":{}}', + stderr="", + ) + + run_mock.side_effect = slow_subprocess + with patch.dict( + os.environ, + { + "DATA_SYNTHESIS_MODEL_PATH": "/models/demo", + "DATA_SYNTHESIS_RUN_MODE": "subprocess", + "DATA_SYNTHESIS_FORCE_SUBPROCESS": "true", + }, + clear=False, + ): + service = SynthesisService() + with ThreadPoolExecutor(max_workers=2) as executor: + first = executor.submit( + service.synthesize_text, + "case-1.txt", + "患者出现头晕。", + ["QA"], + False, + ) + second = executor.submit( + service.synthesize_text, + "case-2.txt", + "患者出现咳嗽。", + ["QA"], + False, + ) + self.assertEqual(first.result()["status"], "success") + self.assertEqual(second.result()["status"], "success") + + self.assertEqual(max_active, 1) + + def test_subprocess_env_defaults_to_hot_model_mode(self): + with patch.dict( + os.environ, + { + "DATA_SYNTHESIS_MODEL_PATH": "/models/demo", + "DATA_SYNTHESIS_RUN_MODE": "subprocess", + }, + clear=False, + ): + service = SynthesisService(synthesizer=_FakeSynthesizer()) + + self.assertEqual(service.run_mode, "inprocess") + + def test_model_initialization_and_generation_use_same_worker_thread(self): + with patch.object(SynthesisService, "_build_synthesizer", side_effect=_ThreadAffinitySynthesizer): + service = SynthesisService(model_path="/models/demo") + first = service.synthesize_text( + "case-1.txt", + "患者出现头晕。", + task_types=["QA"], + include_metrics=False, + ) + with ThreadPoolExecutor(max_workers=1) as executor: + second = executor.submit( + service.synthesize_text, + "case-2.txt", + "患者出现咳嗽。", + ["QA"], + False, + ).result() + + self.assertEqual(first["status"], "success") + self.assertEqual(second["status"], "success") + if __name__ == "__main__": unittest.main() diff --git a/runtime/ops/mapper/data_synthesis/test_cases/README.md b/runtime/ops/mapper/data_synthesis/test_cases/README.md index 3d8503d5..f9138012 100644 --- a/runtime/ops/mapper/data_synthesis/test_cases/README.md +++ b/runtime/ops/mapper/data_synthesis/test_cases/README.md @@ -1,41 +1,23 @@ # data_synthesis 测试用例 -本目录提供公开数据集来源说明和轻量可运行样例,用于验收平台复测数据合成算子。 - -## 公开数据集来源 - -- `cMedQA2` - 中文医学问答数据集,适合验证中文医学 QA、CoT 和 Preference 数据生成。 - - -- `PubMedQA` - 生物医学问答数据集,适合验证专业医学英文文本生成。 - - - - -## 本目录样例 - -- `example_input/cmedqa2_style_case_cn.txt` - 基于 `cMedQA2` 场景整理的中文医学问答输入。 -- `example_input/pubmedqa_style_case_en.txt` - 基于 `PubMedQA` 场景整理的英文医学问答输入。 -- `cases.json` - 记录测试样例来源、推荐任务类型和验收检查点。 - -## 平台测试步骤 - -1. 部署 `data_synthesis` 独立服务,确认 DataMate 运行环境能访问服务地址。 -2. 在 DataMate 算子市场上传 `../data_synthesis.zip`。 -3. 创建任务并上传 `example_input/` 下任一文本文件。 -4. 算子参数设置 `taskTypes=QA,CoT,Preference`。 -5. 运行任务并下载输出 JSON。 - -## 检查项 - -- 输出 JSON 包含 `source_file`、`task_types`、`results`、`status`。 -- `results.QA`、`results.CoT`、`results.Preference` 均非空。 -- `QA` 至少包含 `question`、`answer`。 -- `CoT` 至少包含 `question`、`rationale`、`final_answer`。 -- `Preference` 至少包含 `question`、`chosen`、`rejected`、`preference_reason`。 -- 失败样本应标记为 `failed`,不应伪装成成功结果。 +本目录提供 30 个中文测试用例,用于在 DataMate 平台验证数据合成算子。测试输入均为中文医疗问答、中文病例摘要或中文健康咨询风格文本。 + +## 公开数据来源参考 + +- cMedQA2:https://github.com/zhangsheng93/cMedQA2 +- medical-o1-reasoning-SFT:https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT + +上述链接用于说明测试样例的数据风格来源;本目录中的输入文件已整理为可直接上传平台的小型中文样例。 + +## 测试方法 + +1. 在 DataMate 平台上传并启用 data_synthesis 算子。 +2. 只上传 `example_input` 目录下的 `.txt` 输入文件,不要上传 `cases.json`、`README.md` 或整个 `test_cases` 外层目录。 +3. 参数 `taskTypes` 填写 `QA,CoT,Preference`。 +4. 运行完成后下载结果 JSON。 +5. 对照 `cases.json` 中的 `checks` 检查 QA、CoT、Preference 三类结果是否存在、是否为中文、是否没有乱码。 + +## 目录说明 + +- `cases.json`:30 个中文测试 case 的清单和验收检查点。 +- `example_input/*.txt`:30 个可直接上传 DataMate 的中文输入文件。 diff --git a/runtime/ops/mapper/data_synthesis/test_cases/cases.json b/runtime/ops/mapper/data_synthesis/test_cases/cases.json index 2e148be8..db81a8f9 100644 --- a/runtime/ops/mapper/data_synthesis/test_cases/cases.json +++ b/runtime/ops/mapper/data_synthesis/test_cases/cases.json @@ -1,42 +1,602 @@ [ - { - "id": "cn_medical_consultation_cmedqa2", - "operator": "data_synthesis", - "dataset": "cMedQA2", - "input_file": "example_input/cmedqa2_style_case_cn.txt", - "source_urls": [ - "https://github.com/zhangsheng93/cMedQA2", - "https://huggingface.co/datasets/fzkuji/cMedQA2" - ], - "purpose": "验证中文医疗咨询文本生成 QA、CoT、Preference 三类结果", - "run_parameters": { - "taskTypes": "QA,CoT,Preference" - }, - "checks": [ - "results.QA 非空", - "results.CoT 非空", - "results.Preference 非空", - "每类结果字段完整" - ] - }, - { - "id": "biomedical_research_pubmedqa", - "operator": "data_synthesis", - "dataset": "PubMedQA", - "input_file": "example_input/pubmedqa_style_case_en.txt", - "source_urls": [ - "https://github.com/pubmedqa/pubmedqa", - "https://huggingface.co/datasets/qiaojin/PubMedQA", - "https://arxiv.org/abs/1909.06146" - ], - "purpose": "验证科研医学文本也能生成结构化 QA 与 CoT", - "run_parameters": { - "taskTypes": "QA,CoT,Preference" - }, - "checks": [ - "输出 JSON 非空", - "QA 与 CoT 结果可读", - "Preference 不为空" - ] - } -] + { + "id": "data_synthesis_case_01", + "operator": "data_synthesis", + "dataset": "cMedQA2", + "input_file": "example_input/ds_case_01.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_02", + "operator": "data_synthesis", + "dataset": "中文医疗问答公开语料", + "input_file": "example_input/ds_case_02.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_03", + "operator": "data_synthesis", + "dataset": "medical-o1-reasoning-SFT", + "input_file": "example_input/ds_case_03.txt", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_04", + "operator": "data_synthesis", + "dataset": "medical-o1-reasoning-SFT", + "input_file": "example_input/ds_case_04.txt", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_05", + "operator": "data_synthesis", + "dataset": "中文临床病例公开样式", + "input_file": "example_input/ds_case_05.txt", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_06", + "operator": "data_synthesis", + "dataset": "cMedQA2", + "input_file": "example_input/ds_case_06.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_07", + "operator": "data_synthesis", + "dataset": "中文医疗问答公开语料", + "input_file": "example_input/ds_case_07.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_08", + "operator": "data_synthesis", + "dataset": "medical-o1-reasoning-SFT", + "input_file": "example_input/ds_case_08.txt", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_09", + "operator": "data_synthesis", + "dataset": "中文健康科普公开样式", + "input_file": "example_input/ds_case_09.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_10", + "operator": "data_synthesis", + "dataset": "中文临床病例公开样式", + "input_file": "example_input/ds_case_10.txt", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_11", + "operator": "data_synthesis", + "dataset": "cMedQA2", + "input_file": "example_input/ds_case_11.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_12", + "operator": "data_synthesis", + "dataset": "中文医疗问答公开语料", + "input_file": "example_input/ds_case_12.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_13", + "operator": "data_synthesis", + "dataset": "medical-o1-reasoning-SFT", + "input_file": "example_input/ds_case_13.txt", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_14", + "operator": "data_synthesis", + "dataset": "中文临床病例公开样式", + "input_file": "example_input/ds_case_14.txt", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_15", + "operator": "data_synthesis", + "dataset": "cMedQA2", + "input_file": "example_input/ds_case_15.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_16", + "operator": "data_synthesis", + "dataset": "中文健康科普公开样式", + "input_file": "example_input/ds_case_16.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_17", + "operator": "data_synthesis", + "dataset": "medical-o1-reasoning-SFT", + "input_file": "example_input/ds_case_17.txt", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_18", + "operator": "data_synthesis", + "dataset": "中文医疗问答公开语料", + "input_file": "example_input/ds_case_18.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_19", + "operator": "data_synthesis", + "dataset": "中文临床病例公开样式", + "input_file": "example_input/ds_case_19.txt", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_20", + "operator": "data_synthesis", + "dataset": "cMedQA2", + "input_file": "example_input/ds_case_20.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_21", + "operator": "data_synthesis", + "dataset": "中文健康科普公开样式", + "input_file": "example_input/ds_case_21.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_22", + "operator": "data_synthesis", + "dataset": "medical-o1-reasoning-SFT", + "input_file": "example_input/ds_case_22.txt", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_23", + "operator": "data_synthesis", + "dataset": "中文医疗问答公开语料", + "input_file": "example_input/ds_case_23.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_24", + "operator": "data_synthesis", + "dataset": "中文临床病例公开样式", + "input_file": "example_input/ds_case_24.txt", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_25", + "operator": "data_synthesis", + "dataset": "cMedQA2", + "input_file": "example_input/ds_case_25.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_26", + "operator": "data_synthesis", + "dataset": "中文健康科普公开样式", + "input_file": "example_input/ds_case_26.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_27", + "operator": "data_synthesis", + "dataset": "medical-o1-reasoning-SFT", + "input_file": "example_input/ds_case_27.txt", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_28", + "operator": "data_synthesis", + "dataset": "中文医疗问答公开语料", + "input_file": "example_input/ds_case_28.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_29", + "operator": "data_synthesis", + "dataset": "中文临床病例公开样式", + "input_file": "example_input/ds_case_29.txt", + "source_urls": [ + "https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + }, + { + "id": "data_synthesis_case_30", + "operator": "data_synthesis", + "dataset": "cMedQA2", + "input_file": "example_input/ds_case_30.txt", + "source_urls": [ + "https://github.com/zhangsheng93/cMedQA2" + ], + "purpose": "验证中文医疗文本输入下,算子能够生成 QA、CoT、Preference 三类结构化合成数据。", + "run_parameters": { + "taskTypes": "QA,CoT,Preference" + }, + "checks": [ + "输出必须是合法 JSON。", + "results.QA、results.CoT、results.Preference 三类结果均应存在。", + "每类结果应包含 status 字段;成功结果不得为空。", + "Preference 结果应包含 question、chosen、rejected、preference_reason 等关键字段。", + "输出内容应为中文,不应出现乱码或英文样例正文。" + ] + } +] \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/cmedqa2_style_case_cn.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/cmedqa2_style_case_cn.txt deleted file mode 100644 index 5de3ffa4..00000000 --- a/runtime/ops/mapper/data_synthesis/test_cases/example_input/cmedqa2_style_case_cn.txt +++ /dev/null @@ -1,7 +0,0 @@ -来源数据集风格:cMedQA2(中文医疗问答) - -患者咨询文本: -我今年 56 岁,已有多年高血压病史,平时服用氨氯地平控制血压。最近一周出现轻度踝部水肿,血压大多在 145/92 mmHg 左右。请问这种情况是否需要调整用药?日常应该如何监测血压和生活方式管理? - -验收目标: -请基于以上文本生成 QA、CoT、Preference 三类结构化数据。 diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_01.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_01.txt new file mode 100644 index 00000000..17bdd469 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_01.txt @@ -0,0 +1,6 @@ +测试编号:DS-01 +数据来源风格:cMedQA2 + +患者咨询:我今年56岁,有多年高血压病史,最近一周晨起血压多在145/92mmHg左右,偶尔头晕,没有胸痛。请基于这段中文医疗咨询生成QA、CoT和Preference数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_02.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_02.txt new file mode 100644 index 00000000..15297a17 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_02.txt @@ -0,0 +1,6 @@ +测试编号:DS-02 +数据来源风格:中文医疗问答公开语料 + +患者咨询:2型糖尿病患者空腹血糖经常在8.2mmol/L左右,餐后血糖偏高,最近想了解饮食控制和运动安排。请生成中文问答、推理链和偏好样本。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_03.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_03.txt new file mode 100644 index 00000000..95eb347e --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_03.txt @@ -0,0 +1,6 @@ +测试编号:DS-03 +数据来源风格:medical-o1-reasoning-SFT + +病例摘要:49岁男性,解大便后突发右下腹疼痛3小时,右侧腹股沟区可触及4cm包块,腹部X线见阶梯状液气平。请生成诊断分析相关QA、CoT和Preference数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_04.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_04.txt new file mode 100644 index 00000000..402139c0 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_04.txt @@ -0,0 +1,6 @@ +测试编号:DS-04 +数据来源风格:medical-o1-reasoning-SFT + +病例摘要:59岁女性,反酸烧心30年,咳嗽喘息5年,胃镜提示反流性食管炎LA-C和食管裂孔疝。请生成病史分析相关中文合成数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_05.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_05.txt new file mode 100644 index 00000000..29b9b0d3 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_05.txt @@ -0,0 +1,6 @@ +测试编号:DS-05 +数据来源风格:中文临床病例公开样式 + +患者资料:男,68岁,慢性阻塞性肺疾病10年,近日咳嗽咳痰加重,痰黄,活动后气促明显,体温38.2℃。请生成疾病判断、处理建议和偏好比较数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_06.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_06.txt new file mode 100644 index 00000000..349b1fca --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_06.txt @@ -0,0 +1,6 @@ +测试编号:DS-06 +数据来源风格:cMedQA2 + +患者咨询:孕24周,最近出现轻度贫血,血红蛋白102g/L,担心补铁影响胎儿。请围绕孕期贫血科普生成中文QA、CoT和Preference。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_07.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_07.txt new file mode 100644 index 00000000..0268209d --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_07.txt @@ -0,0 +1,6 @@ +测试编号:DS-07 +数据来源风格:中文医疗问答公开语料 + +患者咨询:8岁儿童反复咳嗽两周,夜间明显,无发热,既往有过敏性鼻炎。请生成儿科问答、推理解释和优劣回答样本。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_08.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_08.txt new file mode 100644 index 00000000..a28fd808 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_08.txt @@ -0,0 +1,6 @@ +测试编号:DS-08 +数据来源风格:medical-o1-reasoning-SFT + +病例摘要:女性34岁,双下肢麻木无力一年半,感觉障碍自下而上发展,体检提示脊髓半侧损害。请生成诊断依据相关的中文合成数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_09.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_09.txt new file mode 100644 index 00000000..d29fe3bd --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_09.txt @@ -0,0 +1,6 @@ +测试编号:DS-09 +数据来源风格:中文健康科普公开样式 + +健康咨询:体检发现低密度脂蛋白胆固醇4.1mmol/L,父亲有冠心病史,想知道是否需要药物治疗。请生成中文医学QA、CoT和Preference。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_10.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_10.txt new file mode 100644 index 00000000..5fa2969d --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_10.txt @@ -0,0 +1,6 @@ +测试编号:DS-10 +数据来源风格:中文临床病例公开样式 + +病例摘要:女,45岁,反复上腹痛半年,餐后加重,胃镜提示胃窦溃疡,幽门螺杆菌阳性。请生成诊疗思路相关的合成数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_11.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_11.txt new file mode 100644 index 00000000..3bdd0fc4 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_11.txt @@ -0,0 +1,6 @@ +测试编号:DS-11 +数据来源风格:cMedQA2 + +患者咨询:我最近连续失眠三周,入睡困难,白天注意力下降,不想长期吃安眠药。请生成睡眠障碍相关QA、CoT和Preference数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_12.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_12.txt new file mode 100644 index 00000000..9c5af2dc --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_12.txt @@ -0,0 +1,6 @@ +测试编号:DS-12 +数据来源风格:中文医疗问答公开语料 + +患者咨询:甲状腺结节超声提示TI-RADS 4A,大小0.8cm,没有明显症状,担心是否需要穿刺。请生成中文医学合成数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_13.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_13.txt new file mode 100644 index 00000000..ebc86703 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_13.txt @@ -0,0 +1,6 @@ +测试编号:DS-13 +数据来源风格:medical-o1-reasoning-SFT + +病例摘要:男,72岁,突发言语不清和右侧肢体无力2小时,高血压病史,头颅CT未见出血。请生成急性脑卒中评估相关数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_14.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_14.txt new file mode 100644 index 00000000..bcc6f429 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_14.txt @@ -0,0 +1,6 @@ +测试编号:DS-14 +数据来源风格:中文临床病例公开样式 + +病例摘要:女,30岁,尿频尿急尿痛2天,伴下腹不适,无腰痛发热,尿常规白细胞升高。请生成泌尿感染相关QA、CoT和Preference。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_15.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_15.txt new file mode 100644 index 00000000..bbdb9794 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_15.txt @@ -0,0 +1,6 @@ +测试编号:DS-15 +数据来源风格:cMedQA2 + +患者咨询:长期伏案工作后颈肩疼痛,偶尔手麻,核磁提示颈椎间盘轻度突出。请生成康复建议相关中文合成数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_16.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_16.txt new file mode 100644 index 00000000..f2927501 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_16.txt @@ -0,0 +1,6 @@ +测试编号:DS-16 +数据来源风格:中文健康科普公开样式 + +健康咨询:老人接种流感疫苗后第二天低热和乏力,家属担心是否属于严重不良反应。请生成疫苗科普相关QA、CoT和Preference。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_17.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_17.txt new file mode 100644 index 00000000..17ab30d1 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_17.txt @@ -0,0 +1,6 @@ +测试编号:DS-17 +数据来源风格:medical-o1-reasoning-SFT + +病例摘要:男,60岁,胸骨后压榨样疼痛30分钟,向左肩放射,伴大汗,心电图提示ST段抬高。请生成急性冠脉综合征相关数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_18.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_18.txt new file mode 100644 index 00000000..5743bc0b --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_18.txt @@ -0,0 +1,6 @@ +测试编号:DS-18 +数据来源风格:中文医疗问答公开语料 + +患者咨询:慢性乙肝携带者,肝功能正常,HBV DNA轻度升高,想知道是否需要抗病毒治疗。请生成中文合成数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_19.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_19.txt new file mode 100644 index 00000000..74a7dde2 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_19.txt @@ -0,0 +1,6 @@ +测试编号:DS-19 +数据来源风格:中文临床病例公开样式 + +病例摘要:女,66岁,膝关节疼痛多年,上下楼明显,X线提示骨关节炎改变。请生成诊断和非药物治疗相关QA、CoT和Preference。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_20.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_20.txt new file mode 100644 index 00000000..7478862f --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_20.txt @@ -0,0 +1,6 @@ +测试编号:DS-20 +数据来源风格:cMedQA2 + +患者咨询:过敏性鼻炎反复发作,打喷嚏流清涕,春秋季明显,想了解鼻喷激素是否安全。请生成中文医学合成数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_21.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_21.txt new file mode 100644 index 00000000..3ba48a67 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_21.txt @@ -0,0 +1,6 @@ +测试编号:DS-21 +数据来源风格:中文健康科普公开样式 + +健康咨询:体检尿酸480μmol/L,平时爱吃海鲜和啤酒,没有痛风发作史。请生成高尿酸管理相关QA、CoT和Preference。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_22.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_22.txt new file mode 100644 index 00000000..12534309 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_22.txt @@ -0,0 +1,6 @@ +测试编号:DS-22 +数据来源风格:medical-o1-reasoning-SFT + +病例摘要:男,40岁,反复黑便一周,乏力头晕,血红蛋白78g/L,既往有十二指肠溃疡。请生成消化道出血相关合成数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_23.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_23.txt new file mode 100644 index 00000000..2909f29f --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_23.txt @@ -0,0 +1,6 @@ +测试编号:DS-23 +数据来源风格:中文医疗问答公开语料 + +患者咨询:乳腺超声提示BI-RADS 3类结节,边界清楚,医生建议随访,患者担心恶变。请生成中文QA、CoT和Preference。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_24.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_24.txt new file mode 100644 index 00000000..58b984d1 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_24.txt @@ -0,0 +1,6 @@ +测试编号:DS-24 +数据来源风格:中文临床病例公开样式 + +病例摘要:女,52岁,近半年月经紊乱、潮热盗汗、情绪波动,想了解围绝经期管理。请生成相关中文合成数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_25.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_25.txt new file mode 100644 index 00000000..1d558c2f --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_25.txt @@ -0,0 +1,6 @@ +测试编号:DS-25 +数据来源风格:cMedQA2 + +患者咨询:服用阿莫西林后出现皮疹和瘙痒,无呼吸困难,想知道是否还能继续服药。请生成药物过敏相关QA、CoT和Preference。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_26.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_26.txt new file mode 100644 index 00000000..68f3d878 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_26.txt @@ -0,0 +1,6 @@ +测试编号:DS-26 +数据来源风格:中文健康科普公开样式 + +健康咨询:长期饮酒者体检发现谷丙转氨酶升高,腹部超声提示脂肪肝。请生成生活方式干预和就医建议相关数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_27.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_27.txt new file mode 100644 index 00000000..79ab7f07 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_27.txt @@ -0,0 +1,6 @@ +测试编号:DS-27 +数据来源风格:medical-o1-reasoning-SFT + +病例摘要:男,28岁,运动后突发胸闷气短,右侧胸痛,胸片提示右侧气胸。请生成急诊处理相关中文合成数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_28.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_28.txt new file mode 100644 index 00000000..88319585 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_28.txt @@ -0,0 +1,6 @@ +测试编号:DS-28 +数据来源风格:中文医疗问答公开语料 + +患者咨询:儿童发热38.7℃,精神尚可,家长想知道退热药如何选择以及何时就医。请生成儿科发热相关QA、CoT和Preference。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_29.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_29.txt new file mode 100644 index 00000000..7ace2ed6 --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_29.txt @@ -0,0 +1,6 @@ +测试编号:DS-29 +数据来源风格:中文临床病例公开样式 + +病例摘要:女,70岁,反复跌倒,骨密度提示骨质疏松,近期腰背痛加重。请生成骨质疏松评估和管理相关数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_30.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_30.txt new file mode 100644 index 00000000..51f322be --- /dev/null +++ b/runtime/ops/mapper/data_synthesis/test_cases/example_input/ds_case_30.txt @@ -0,0 +1,6 @@ +测试编号:DS-30 +数据来源风格:cMedQA2 + +患者咨询:新冠感染后两周仍有乏力和轻微咳嗽,无发热和气促,想了解恢复期注意事项。请生成中文QA、CoT和Preference数据。 + +生成要求:请输出结构化中文结果,覆盖 QA、CoT、Preference 三类数据;问题、答案、推理说明和偏好理由均应忠实于输入文本,不要编造与原文无关的事实。 \ No newline at end of file diff --git a/runtime/ops/mapper/data_synthesis/test_cases/example_input/pubmedqa_style_case_en.txt b/runtime/ops/mapper/data_synthesis/test_cases/example_input/pubmedqa_style_case_en.txt deleted file mode 100644 index 47e26507..00000000 --- a/runtime/ops/mapper/data_synthesis/test_cases/example_input/pubmedqa_style_case_en.txt +++ /dev/null @@ -1,10 +0,0 @@ -Source style: PubMedQA (biomedical research QA) - -Research question: -Can home blood pressure telemonitoring improve blood pressure control in patients with hypertension compared with usual care? - -Abstract-style context: -Several randomized studies have evaluated home blood pressure telemonitoring for adults with hypertension. The intervention usually combines home measurements, remote transmission of readings, and clinician feedback. Reported outcomes commonly include systolic blood pressure reduction, medication adjustment, and adherence to long-term follow-up. - -Acceptance target: -Generate QA, CoT, and Preference records from the text above. diff --git a/runtime/ops/mapper/unstructuredio/NPU_ENV_CHECK_REPORT.md b/runtime/ops/mapper/unstructuredio/NPU_ENV_CHECK_REPORT.md deleted file mode 100644 index 27c4bb07..00000000 --- a/runtime/ops/mapper/unstructuredio/NPU_ENV_CHECK_REPORT.md +++ /dev/null @@ -1,68 +0,0 @@ -# unstructuredio NPU 环境自检报告 - -## 自检环境 - -- 服务器:910b-jss -- 测试容器:huizhi -- 测试目录:临时工作目录,非交付固定路径。 -- NPU 选择:ASCEND_RT_VISIBLE_DEVICES=6 - -## 已验证通过 - -- Torch-NPU 可用:`torch_npu==2.7.1` 可正常 import。 -- Torch NPU 设备可用:`torch.npu.is_available()` 返回 True。 -- YOLOX PT 版面模型文件已按 README 约定挂载,并可通过 `UNSTRUCTUREDIO_YOLOX_MODEL_PATH` 覆盖。 -- YOLOX 源码目录已按 README 约定挂载,并可通过 `UNSTRUCTUREDIO_YOLOX_SRC_PATH` 覆盖。 -- PaddleOCR 本地模型目录存在:det、rec、cls 三类模型均已放置。 -- `check_npu_runtime.py` 已采用子进程隔离检查 Torch-NPU 与 Paddle-NPU,并注入 Ascend/NNAL 动态库路径,避免同进程冲突和库路径误判。`process.py` 主进程和 `ocr_npu_adapter.py` worker 也已统一注入 Ascend/NNAL 动态库路径。 - -## 当前未通过项 - -### PaddleOCR-NPU - -当前 `huizhi` 容器中版本如下: - -- `paddlepaddle==3.3.1` -- `paddle-custom-npu==3.3.0` -- `paddleocr==2.7.3` -- CANN/driver:CANN 8.5.1,driver 25.5.2 - -现象:加载 `paddle-custom-npu` 时进入 `aclInit/rtGetDevMsg` 初始化失败: - -```text -Call aclInit(nullptr) failed : 500000 at file /paddle/backends/npu/runtime/runtime.cc line 403 -``` - -已确认 `check_npu_runtime.py` 会注入 Ascend/NNAL 动态库路径,因此该问题不是模型路径缺失,也不是 `libmki.so` / `LD_LIBRARY_PATH` 缺失,而是当前 Paddle custom NPU 组件与容器/驱动组合的兼容问题。 - -补充验证:已在独立临时容器 `huizhi-paddle30-venv` 中创建隔离 venv,并按 Paddle 官方 NPU 推荐组合安装: - -- `paddlepaddle==3.0.0` -- `paddle-custom-npu==3.0.0` -- `paddleocr==2.7.3` - -该组合仍在 `rtGetDevMsg/aclInit` 阶段失败,错误同样为: - -```text -chipType=0 does not support get device msg feature -Call aclInit(nullptr) failed : 500000 at file /paddle/backends/npu/runtime/runtime.cc line 403 -``` - -因此当前阻塞点不是算子代码、OCR 模型路径、动态库路径,也不是单纯的 Paddle 3.3/3.0 版本选择,而是 910b-jss 当前主机驱动/CANN/设备信息接口与 Paddle custom NPU runtime 不兼容。 - -### DOCX 严格模式 - -当前 `huizhi` 容器没有 `soffice` / LibreOffice。DOCX/DOC 严格模式需要先转 PDF 再复用 PDF NPU 链路,因此缺少 `soffice` 时会直接失败,不会静默回退 CPU fast path。 - -## 算子行为 - -- 普通模式:优先尝试 NPU 链路;NPU/OCR 不可用时回退 `fast/auto`,并在 `mode` 中标识 fallback。 -- 严格模式:设置 `requireNpuModels=true` 或 `UNSTRUCTUREDIO_REQUIRE_NPU_MODELS=1` 后,任何 NPU 组件不可用都会直接失败;DOCX/DOC 严格模式只接受完整 `pdf-npu-ocr-hi_res` 视觉链路,不接受只有版面 NPU、OCR 未走 NPU 的结果。 -- 当前交付不会把 PaddleOCR-NPU 误报为成功。 - -## 建议验收环境要求 - -- 使用与 Paddle 官方 NPU wheel 匹配的 CANN/driver/container 组合,或直接使用 Paddle 官方 NPU 标准镜像。 -- 预置 `paddlepaddle`、`paddle-custom-npu`、`paddleocr`,并通过 `python check_npu_runtime.py` 验证 `paddle` 与 `paddleocr` 均可 import。 -- DOCX/DOC 严格验收需安装 `LibreOffice/soffice`。 -- 模型路径按 README 说明挂载到 `/models/unstructuredio/...` 或用环境变量覆盖。 diff --git a/runtime/ops/mapper/unstructuredio/README.md b/runtime/ops/mapper/unstructuredio/README.md index 8982f0bc..c5e64583 100644 --- a/runtime/ops/mapper/unstructuredio/README.md +++ b/runtime/ops/mapper/unstructuredio/README.md @@ -37,14 +37,6 @@ - `UNSTRUCTUREDIO_OCR_CLS_MODEL_DIR=/models/unstructuredio/paddleocr/ch_ppocr_mobile_v2.0_cls_infer` - `UNSTRUCTUREDIO_TABLE_MODEL_PATH=/models/unstructuredio/table-transformer-structure-recognition` -路径说明: - -- `operator_src/`、`test_cases/` 等仓库内目录均使用相对路径说明,迁移到其他机器后保持目录结构即可。 -- `/models`、`/model` 是容器内模型挂载点,不是主机固定路径。验收方可把主机任意模型目录挂载到该容器内路径,或通过上述环境变量改成其他容器内路径。 -- `/tmp` 仅用于运行时临时文件和 Paddle CPU 隔离目录,不承载交付数据;如运行环境限制 `/tmp`,可通过 `TMPDIR` 或 `OCR_ADAPTER_CPU_CUSTOM_DEVICE_ROOT` 调整。 -- `/usr/local/Ascend/...` 是 Ascend 驱动、CANN、NNAL 的容器内标准库路径;如镜像路径不同,应先通过容器挂载或 `LD_LIBRARY_PATH` 提供等价路径。 -- `HF_ENDPOINT` 默认指向 `https://hf-mirror.com`,只用于拦截/镜像 HuggingFace 请求;正式验收建议本地预置模型,避免运行时访问外网。 - 表格结构模型不存在时,算子会关闭 `infer_table_structure`,避免运行时访问远程模型;PDF 表格标题仍会做轻量补强和合并。 ## NPU 运行依赖 diff --git a/runtime/ops/mapper/unstructuredio/operator_src/README.md b/runtime/ops/mapper/unstructuredio/operator_src/README.md index 528c4326..a81c372a 100644 --- a/runtime/ops/mapper/unstructuredio/operator_src/README.md +++ b/runtime/ops/mapper/unstructuredio/operator_src/README.md @@ -35,18 +35,15 @@ - `UNSTRUCTUREDIO_OCR_CLS_MODEL_DIR`:默认 `/models/unstructuredio/paddleocr/ch_ppocr_mobile_v2.0_cls_infer`。 - `UNSTRUCTUREDIO_TABLE_MODEL_PATH`:默认 `/models/unstructuredio/table-transformer-structure-recognition`。 -路径说明: - -- 默认模型路径均为容器内路径,不绑定任何主机目录;迁移机器时只需要把主机模型目录挂载到容器内 `/models` 或 `/model`,或通过环境变量覆盖。 -- `adapters/YOLOX-main` 和 `operator_src/YOLOX-main` 是算子内相对候选路径;如果不随算子携带 YOLOX 源码,应设置 `UNSTRUCTUREDIO_YOLOX_SRC_PATH`。 -- `/tmp` 仅用于临时 JSON、临时输出和 Paddle CPU 隔离目录;可通过系统 `TMPDIR` 或 `OCR_ADAPTER_CPU_CUSTOM_DEVICE_ROOT` 覆盖。 -- Ascend 相关 `/usr/local/Ascend/...` 是容器内标准库路径;非标准镜像需要通过挂载或 `LD_LIBRARY_PATH` 提供等价路径。 - 表格结构模型不存在时会关闭 `infer_table_structure`,避免访问远程模型。 ## 验证 -本目录不随交付提交开发期单测代码;验收测试样例保留在上一级 `test_cases/` 目录。 +本地单测: + +```bash +python -m pytest operator_src/tests -q +``` 验收环境自检: diff --git a/runtime/ops/mapper/unstructuredio/operator_src/adapters/requirements_npu_v1.2_stable.txt b/runtime/ops/mapper/unstructuredio/operator_src/adapters/requirements_npu_v1.2_stable.txt index 98ad8c5b..8352d802 100644 --- a/runtime/ops/mapper/unstructuredio/operator_src/adapters/requirements_npu_v1.2_stable.txt +++ b/runtime/ops/mapper/unstructuredio/operator_src/adapters/requirements_npu_v1.2_stable.txt @@ -14,12 +14,12 @@ opencv-python-headless==4.9.0.80 onnxruntime==1.23.2 einops==0.8.2 loguru==0.7.3 -pi_heif==1.0.0 +pi-heif==1.1.1 pikepdf==9.8.1 -pdf2image -pypdfium2 +pdf2image==1.17.0 +pypdfium2==4.30.0 # 系统依赖 # - Ascend CANN/driver runtime -# - poppler/pdf render dependencies required by unstructured/pdf2image +# - poppler/pdf render dependencies required by unstructured/pdf2image==1.17.0 # - LibreOffice/soffice for DOCX/DOC strict NPU mode diff --git a/runtime/ops/mapper/unstructuredio/operator_src/process.py b/runtime/ops/mapper/unstructuredio/operator_src/process.py index 21366b0d..f8652da9 100644 --- a/runtime/ops/mapper/unstructuredio/operator_src/process.py +++ b/runtime/ops/mapper/unstructuredio/operator_src/process.py @@ -40,6 +40,7 @@ def _configure_nltk_import_environment() -> None: os.getenv("UNSTRUCTUREDIO_NLTK_DATA", ""), "/models/unstructuredio/nltk_data", "/model/unstructuredio/nltk_data", + "/home/o_pengjunjie/huizhi/unstructuredio_models/nltk_data", ] for preferred in preferred_paths: if preferred and Path(preferred).exists() and not _nltk_path_has_bad_zip(preferred): diff --git a/runtime/ops/mapper/unstructuredio/operator_src/requirements.txt b/runtime/ops/mapper/unstructuredio/operator_src/requirements.txt index cb803ce8..4b415676 100644 --- a/runtime/ops/mapper/unstructuredio/operator_src/requirements.txt +++ b/runtime/ops/mapper/unstructuredio/operator_src/requirements.txt @@ -1,2 +1,26 @@ -unstructured -python-docx +# Core document parsing dependencies verified in datamate-runtime on 910b. +unstructured==0.18.15 +unstructured-inference==1.6.10 +python-docx==1.2.0 +requests==2.32.5 +numpy==2.2.6 +pandas==2.3.3 +opencv-python-headless==4.13.0.92 +safetensors==0.7.0 +transformers==4.57.6 +torch==2.8.0+cpu +torchvision==0.23.0 +pdf2image==1.17.0 +pypdfium2==4.30.0 +pikepdf==10.5.1 +pi-heif==1.1.1 +onnxruntime==1.19.2 +einops==0.8.2 +loguru==0.7.3 +paddlepaddle==3.2.2 +paddleocr==3.3.0 + +# Ascend/NPU optional runtime. +# Install from the Ascend-compatible wheel/index that matches the target CANN +# runtime; importing torch_npu also requires sourcing the CANN environment. +torch-npu==2.8.0 diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_check_npu_runtime.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_check_npu_runtime.py new file mode 100644 index 00000000..0f347920 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_check_npu_runtime.py @@ -0,0 +1,65 @@ +import importlib.util +import subprocess +from pathlib import Path + + +def _load_check_module(): + module_path = Path(__file__).resolve().parents[1] / "check_npu_runtime.py" + spec = importlib.util.spec_from_file_location("check_npu_runtime_under_test", module_path) + module = importlib.util.module_from_spec(spec) + assert spec is not None and spec.loader is not None + spec.loader.exec_module(module) + return module + + +def test_module_probe_runs_each_import_in_isolated_process(monkeypatch): + check = _load_check_module() + commands = [] + + def fake_run(command, **kwargs): + commands.append(command) + return subprocess.CompletedProcess(command, 0, stdout='{"available": true, "version": "x"}\n', stderr="") + + monkeypatch.setattr(check.subprocess, "run", fake_run) + + assert check._module_version("torch_npu") == {"available": True, "version": "x"} + assert commands[0][0] == check.sys.executable + assert "importlib.import_module('torch_npu')" in commands[0][2] + + +def test_main_accepts_split_torch_and_paddle_npu_probe_success(monkeypatch, tmp_path, capsys): + check = _load_check_module() + model_dir = tmp_path / "model" + model_dir.mkdir() + + monkeypatch.setattr(check, "_module_version", lambda name: {"available": True, "version": name}) + monkeypatch.setenv("UNSTRUCTUREDIO_YOLOX_MODEL_PATH", str(model_dir)) + monkeypatch.setenv("UNSTRUCTUREDIO_YOLOX_SRC_PATH", str(model_dir)) + monkeypatch.setenv("UNSTRUCTUREDIO_OCR_DET_MODEL_DIR", str(model_dir)) + monkeypatch.setenv("UNSTRUCTUREDIO_OCR_REC_MODEL_DIR", str(model_dir)) + monkeypatch.setenv("UNSTRUCTUREDIO_OCR_CLS_MODEL_DIR", str(model_dir)) + + assert check.main() == 0 + report = capsys.readouterr().out + assert '"torch_npu"' in report + assert '"paddleocr"' in report + + +def test_module_probe_injects_ascend_library_paths(monkeypatch): + check = _load_check_module() + seen_envs = [] + + def fake_exists(path): + return path in {"/opt/ascend/lib", "/tmp/existing"} + + def fake_run(command, **kwargs): + seen_envs.append(kwargs["env"]) + return subprocess.CompletedProcess(command, 0, stdout='{"available": true, "version": "x"}\n', stderr="") + + monkeypatch.setattr(check.os.path, "exists", fake_exists) + monkeypatch.setattr(check, "ASCEND_NPU_LIBRARY_PATHS", ("/opt/ascend/lib", "/missing")) + monkeypatch.setenv("LD_LIBRARY_PATH", "/tmp/existing") + monkeypatch.setattr(check.subprocess, "run", fake_run) + + assert check._module_version("paddle")["available"] is True + assert seen_envs[0]["LD_LIBRARY_PATH"].split(":") == ["/opt/ascend/lib", "/tmp/existing"] diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_npu_adapter_cpu_fallback.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_npu_adapter_cpu_fallback.py new file mode 100644 index 00000000..12ea3453 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_npu_adapter_cpu_fallback.py @@ -0,0 +1,31 @@ +import importlib.util +import sys +import types +from pathlib import Path + + +def _load_npu_adapter(): + if "torch_npu" not in sys.modules: + sys.modules["torch_npu"] = types.ModuleType("torch_npu") + module_path = Path(__file__).resolve().parents[1] / "adapters" / "npu_adapter.py" + spec = importlib.util.spec_from_file_location("npu_adapter_under_test", module_path) + module = importlib.util.module_from_spec(spec) + assert spec is not None and spec.loader is not None + spec.loader.exec_module(module) + return module + + +def test_npu_get_model_delegates_to_original_loader_when_cpu_forced_and_local_model_missing(monkeypatch): + adapter = _load_npu_adapter() + calls = [] + + def original_get_model(model_name, **kwargs): + calls.append((model_name, kwargs)) + return "cpu-model" + + adapter._ORIGINAL_GET_MODEL = original_get_model + monkeypatch.setattr(adapter, "_resolve_yolox_model_path", lambda: str(Path("missing.pt"))) + monkeypatch.setenv("UNSTRUCTUREDIO_FORCE_CPU_MODELS", "1") + + assert adapter.npu_get_model("yolox", foo="bar", password="secret") == "cpu-model" + assert calls == [("yolox", {"foo": "bar"})] diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_ocr_cpu_patch.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_ocr_cpu_patch.py new file mode 100644 index 00000000..8362d754 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_ocr_cpu_patch.py @@ -0,0 +1,45 @@ +import importlib.util +from pathlib import Path + + +def _load_ocr_adapter(): + module_path = Path(__file__).resolve().parents[1] / "adapters" / "ocr_npu_adapter.py" + spec = importlib.util.spec_from_file_location("ocr_adapter_under_test", module_path) + module = importlib.util.module_from_spec(spec) + assert spec is not None and spec.loader is not None + spec.loader.exec_module(module) + return module + + +def test_force_paddle_cpu_patch_does_not_require_native_tesseract(monkeypatch): + adapter = _load_ocr_adapter() + + def fail_native_load(): + raise ModuleNotFoundError("pytesseract") + + monkeypatch.setattr(adapter, "_load_native_tesseract_modules", fail_native_load) + monkeypatch.setenv("OCR_ADAPTER_FORCE_PADDLE_CPU", "1") + + adapter.apply_ocr_patch() + + assert "pytesseract" in adapter.sys.modules + assert "unstructured_pytesseract" in adapter.sys.modules + + +def test_cpu_paddle_availability_check_does_not_import_paddle_in_parent(monkeypatch): + adapter = _load_ocr_adapter() + imported = [] + + def fake_find_spec(name): + return object() if name in {"paddle", "paddleocr"} else None + + def fail_import(name): + imported.append(name) + raise AssertionError("parent process must not import paddle for CPU OCR availability") + + monkeypatch.setattr(adapter.importlib.util, "find_spec", fake_find_spec) + monkeypatch.setattr(adapter.importlib, "import_module", fail_import) + monkeypatch.setenv("OCR_ADAPTER_DEVICE", "cpu") + + assert adapter._paddle_ocr_available() is True + assert imported == [] diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_pdf_npu_ocr_priority.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_pdf_npu_ocr_priority.py new file mode 100644 index 00000000..60584957 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_pdf_npu_ocr_priority.py @@ -0,0 +1,390 @@ +import importlib.util +import os +import sys +import types +from pathlib import Path + + +def _load_process_module(): + datamate = types.ModuleType("datamate") + core = types.ModuleType("datamate.core") + base_op = types.ModuleType("datamate.core.base_op") + + class _Mapper: + def __init__(self, *args, **kwargs): + self.filepath_key = "filepath" + self.filetype_key = "filetype" + self.text_key = "text" + self.target_type_key = "target_type" + + base_op.Mapper = _Mapper + core.base_op = base_op + datamate.core = core + sys.modules["datamate"] = datamate + sys.modules["datamate.core"] = core + sys.modules["datamate.core.base_op"] = base_op + + if "unstructured" not in sys.modules: + unstructured = types.ModuleType("unstructured") + partition = types.ModuleType("unstructured.partition") + auto = types.ModuleType("unstructured.partition.auto") + + def _partition(*args, **kwargs): + raise NotImplementedError("partition_auto stub should not be used in these tests") + + auto.partition = _partition + partition.auto = auto + unstructured.partition = partition + sys.modules["unstructured"] = unstructured + sys.modules["unstructured.partition"] = partition + sys.modules["unstructured.partition.auto"] = auto + + module_path = Path(__file__).resolve().parents[1] / "process.py" + spec = importlib.util.spec_from_file_location("unstructuredio_process_under_test", module_path) + module = importlib.util.module_from_spec(spec) + assert spec is not None and spec.loader is not None + spec.loader.exec_module(module) + return module + + +class _Metadata: + page_number = 1 + coordinates = None + text_as_html = None + + +class _Element: + category = "NarrativeText" + metadata = _Metadata() + + def __init__(self, text): + self.text = text + + +def test_process_disables_nltk_auto_download_before_unstructured_import(monkeypatch): + monkeypatch.delenv("AUTO_DOWNLOAD_NLTK", raising=False) + + _load_process_module() + + assert os.environ["AUTO_DOWNLOAD_NLTK"] == "False" + + +def test_pdf_keeps_fast_result_when_auto_fallback_raises(monkeypatch): + process = _load_process_module() + calls = [] + + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) + monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) + monkeypatch.setattr(process, "_get_ocr_runtime_status", lambda: {"available": False, "device": "npu"}) + + def _partition_pdf(**kwargs): + calls.append(kwargs["strategy"]) + if kwargs["strategy"] == "auto": + raise RuntimeError("simulated auto fallback failure") + return [_Element("x"), _Element("y"), _Element("z")] + + monkeypatch.setattr(process, "partition_pdf", _partition_pdf) + + mapper = process.UnstructuredIOMapper(pdfStrategy="auto") + elements, mode = mapper._extract_pdf(Path("sample.pdf")) + + assert calls == ["fast", "auto"] + assert mode == "pdf-npu-ocr-fallback-fast" + assert [item["text"] for item in elements] == ["x", "y", "z"] + + +def test_pdf_skips_cpu_hi_res_model_fallback_even_when_cpu_ocr_exists(monkeypatch): + process = _load_process_module() + calls = [] + + monkeypatch.delenv("UNSTRUCTUREDIO_TABLE_DEVICE", raising=False) + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) + monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) + monkeypatch.setattr(process, "_has_cpu_ocr_runtime", lambda: True) + monkeypatch.setattr(process, "_get_ocr_runtime_status", lambda: {"available": False, "device": "npu"}) + + def _partition_pdf(**kwargs): + calls.append( + { + "strategy": kwargs["strategy"], + "hi_res_model_name": kwargs.get("hi_res_model_name"), + "table_device": process.os.environ.get("UNSTRUCTUREDIO_TABLE_DEVICE"), + } + ) + return [ + _Element("long enough text from fast fallback one with useful content"), + _Element("long enough text from fast fallback two with useful content"), + _Element("long enough text from fast fallback three with useful content"), + ] + + monkeypatch.setattr(process, "partition_pdf", _partition_pdf) + + mapper = process.UnstructuredIOMapper(pdfStrategy="auto") + elements, mode = mapper._extract_pdf(Path("sample.pdf")) + + assert calls == [{"strategy": "fast", "hi_res_model_name": None, "table_device": None}] + assert mode == "pdf-npu-ocr-fallback-fast" + assert len(elements) == 3 + + +def test_pdf_skips_cpu_hi_res_when_cpu_ocr_runtime_missing(monkeypatch): + process = _load_process_module() + calls = [] + + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) + monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) + monkeypatch.setattr(process, "_has_cpu_ocr_runtime", lambda: False) + monkeypatch.setattr(process, "_get_ocr_runtime_status", lambda: {"available": False, "device": "npu"}) + + def _partition_pdf(**kwargs): + calls.append(kwargs["strategy"]) + return [ + _Element("fast text one with enough useful extracted content"), + _Element("fast text two with enough useful extracted content"), + _Element("fast text three with enough useful extracted content"), + ] + + monkeypatch.setattr(process, "partition_pdf", _partition_pdf) + + mapper = process.UnstructuredIOMapper(pdfStrategy="auto") + elements, mode = mapper._extract_pdf(Path("sample.pdf")) + + assert calls == ["fast"] + assert mode == "pdf-npu-ocr-fallback-fast" + assert len(elements) == 3 + + +def test_pdf_runs_npu_hi_res_when_npu_ocr_is_available(monkeypatch): + process = _load_process_module() + seen_kwargs = [] + + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) + process._NPU_OCR_ADAPTER_STATUS.update({"attempted": True, "npu": True, "ocr": True, "error": None}) + monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) + monkeypatch.setattr( + process, + "_get_ocr_runtime_status", + lambda: {"available": True, "device": "npu", "native_only": False, "is_alive": True}, + ) + + def _partition_pdf(**kwargs): + seen_kwargs.append(kwargs) + return [ + _Element("long enough npu layout text one with useful extracted content"), + _Element("long enough npu layout text two with useful extracted content"), + _Element("long enough npu layout text three with useful extracted content"), + ] + + monkeypatch.setattr(process, "partition_pdf", _partition_pdf) + + mapper = process.UnstructuredIOMapper(pdfStrategy="auto") + elements, mode = mapper._extract_pdf(Path("sample.pdf")) + + assert seen_kwargs[0]["strategy"] == "hi_res" + assert seen_kwargs[0]["hi_res_model_name"] == "yolox" + assert seen_kwargs[0]["ocr_strategy"] == "force" + assert seen_kwargs[0]["ocr_mode"] == "entire_page" + assert mode == "pdf-npu-ocr-hi_res" + assert len(elements) == 3 + + +def test_pdf_uses_fast_path_when_ocr_adapter_is_unavailable(monkeypatch): + process = _load_process_module() + seen_kwargs = [] + + def apply_partial_adapters(): + process._NPU_OCR_ADAPTER_STATUS.update( + {"attempted": True, "npu": True, "ocr": False, "error": "ocr unavailable"} + ) + return False + + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", apply_partial_adapters) + monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) + monkeypatch.setattr(process, "_get_ocr_runtime_status", lambda: {"available": False}) + + def _partition_pdf(**kwargs): + seen_kwargs.append(kwargs) + return [ + _Element("long enough npu layout text one with useful extracted content"), + _Element("long enough npu layout text two with useful extracted content"), + _Element("long enough npu layout text three with useful extracted content"), + ] + + monkeypatch.setattr(process, "partition_pdf", _partition_pdf) + + mapper = process.UnstructuredIOMapper(pdfStrategy="auto") + elements, mode = mapper._extract_pdf(Path("sample.pdf")) + + assert seen_kwargs[0]["strategy"] == "fast" + assert "hi_res_model_name" not in seen_kwargs[0] + assert "ocr_strategy" not in seen_kwargs[0] + assert mode == "pdf-npu-ocr-fallback-fast" + assert len(elements) == 3 + + +def test_pdf_falls_back_when_table_caption_has_no_table(monkeypatch): + process = _load_process_module() + calls = [] + + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) + monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) + monkeypatch.setattr(process, "_has_cpu_ocr_runtime", lambda: False) + monkeypatch.setattr(process, "_get_ocr_runtime_status", lambda: {"available": True, "device": "npu", "native_only": False, "is_alive": True}) + + def _partition_pdf(**kwargs): + calls.append(kwargs["strategy"]) + if kwargs["strategy"] == "hi_res": + return [ + _Element("Attention Is All You Need"), + _Element( + "Table 3: Variations on the Transformer architecture. " + "This line says a table exists but the model did not return a Table element." + ), + _Element("long enough surrounding text with useful extracted content"), + ] + return [ + _Element("fast text one with enough useful extracted content"), + _Element("Table 3: Variations BLEU PPL params 25.8 4.92 65M 26.4 4.75 80M"), + _Element("fast text three with enough useful extracted content"), + ] + + monkeypatch.setattr(process, "partition_pdf", _partition_pdf) + + mapper = process.UnstructuredIOMapper(pdfStrategy="auto") + elements, mode = mapper._extract_pdf(Path("sample.pdf")) + + assert calls[:2] == ["hi_res", "fast"] + assert mode == "pdf-npu-ocr-fallback-fast" + assert any(item["category"] == "Table" for item in elements) + + +def test_pdf_table_body_heuristic_rejects_numeric_citation_paragraph(): + process = _load_process_module() + + text = ( + "Recurrent neural networks, long short-term memory [13] and gated recurrent [7] " + "neural networks in particular, have been firmly established as state of the art " + "approaches in sequence modeling and transduction problems such as language " + "modeling and machine translation [35, 2, 5]. Numerous efforts have since " + "continued to push the boundaries of recurrent language models and encoder-decoder " + "architectures [38, 24, 15]." + ) + + assert process._looks_like_table_body(text) is False + + +def test_pdf_table_body_heuristic_accepts_dense_numeric_table_row(): + process = _load_process_module() + + text = ( + "PPL train steps (dev) 100K 4.92 5.29 5.00 4.91 5.01 5.16 5.01 " + "6.11 5.19 4.88 5.75 4.66 5.12 4.75 5.77 4.95 4.67 5.47 4.92 300K 4.33" + ) + + assert process._looks_like_table_body(text) is True + + +def test_existing_pdf_table_gets_html_when_missing(): + process = _load_process_module() + + items = [ + { + "category": "Table", + "text": "Layer Type Complexity O(n) Self-Attention O(n².d)", + "text_as_html": None, + } + ] + + promoted = process._promote_obvious_pdf_tables(items) + + assert promoted[0]["category"] == "Table" + assert promoted[0]["text_as_html"].startswith("
    ") + + +def test_npu_mode_name_does_not_treat_cpu_ocr_as_npu(monkeypatch): + process = _load_process_module() + process._NPU_OCR_ADAPTER_STATUS.update({"npu": True, "ocr": True}) + monkeypatch.setattr( + process, + "_get_ocr_runtime_status", + lambda: {"available": True, "device": "cpu", "native_only": False, "is_alive": True}, + ) + + assert process._npu_ocr_mode_name() == "pdf-npu-hi_res" + + +def test_apply_adapters_prewarms_cpu_ocr_before_npu_adapter(monkeypatch): + process = _load_process_module() + calls = [] + + fake_ocr = types.ModuleType("ocr_npu_adapter") + + def apply_ocr_patch(): + calls.append("ocr_patch") + + def prewarm_ocr_runtime(): + calls.append("ocr_prewarm") + return {"available": True, "device": "cpu", "native_only": False, "is_alive": True} + + def get_ocr_runtime_status(): + calls.append("ocr_status") + return {"available": True, "device": "cpu", "native_only": False, "is_alive": True} + + fake_ocr.apply_ocr_patch = apply_ocr_patch + fake_ocr.prewarm_ocr_runtime = prewarm_ocr_runtime + fake_ocr.get_ocr_runtime_status = get_ocr_runtime_status + + fake_npu = types.ModuleType("npu_adapter") + + def apply_patches(): + calls.append("npu_patch") + + fake_npu.apply_patches = apply_patches + + monkeypatch.setitem(sys.modules, "ocr_npu_adapter", fake_ocr) + monkeypatch.setitem(sys.modules, "npu_adapter", fake_npu) + monkeypatch.setenv("UNSTRUCTUREDIO_OCR_DEVICE", "cpu") + monkeypatch.setenv("OCR_ADAPTER_FORCE_PADDLE_CPU", "1") + monkeypatch.setenv("UNSTRUCTUREDIO_ENABLE_CPU_OCR_FALLBACK", "1") + + assert process._apply_npu_ocr_adapters() is True + assert calls == ["ocr_patch", "ocr_prewarm", "npu_patch"] + assert process._NPU_OCR_ADAPTER_STATUS["ocr"] is True + assert process._NPU_OCR_ADAPTER_STATUS["npu"] is True + + +def test_apply_adapters_does_not_prewarm_default_npu_ocr(monkeypatch): + process = _load_process_module() + calls = [] + + fake_ocr = types.ModuleType("ocr_npu_adapter") + fake_ocr.apply_ocr_patch = lambda: calls.append("ocr_patch") + fake_ocr.prewarm_ocr_runtime = lambda: calls.append("ocr_prewarm") + fake_ocr.get_ocr_runtime_status = lambda: {"available": False, "device": "npu"} + + fake_npu = types.ModuleType("npu_adapter") + fake_npu.apply_patches = lambda: calls.append("npu_patch") + + monkeypatch.setitem(sys.modules, "ocr_npu_adapter", fake_ocr) + monkeypatch.setitem(sys.modules, "npu_adapter", fake_npu) + monkeypatch.delenv("UNSTRUCTUREDIO_OCR_DEVICE", raising=False) + monkeypatch.delenv("OCR_ADAPTER_DEVICE", raising=False) + + assert process._apply_npu_ocr_adapters() is True + assert calls == ["ocr_patch", "npu_patch"] + + +def test_configure_npu_ocr_environment_overrides_cpu_ocr_request(monkeypatch): + process = _load_process_module() + + monkeypatch.setenv("UNSTRUCTUREDIO_OCR_DEVICE", "cpu") + monkeypatch.setenv("OCR_ADAPTER_DEVICE", "cpu") + monkeypatch.setenv("OCR_ADAPTER_FORCE_PADDLE_CPU", "1") + monkeypatch.delenv("UNSTRUCTUREDIO_ENABLE_CPU_OCR_FALLBACK", raising=False) + monkeypatch.setattr(process, "_prepend_existing_sys_path", lambda path: None) + monkeypatch.setattr(process, "_configure_ascend_runtime_environment", lambda: None) + + process._configure_npu_ocr_environment() + + assert process.os.environ["OCR_ADAPTER_DEVICE"] == "npu" + assert process.os.environ["OCR_ADAPTER_DISABLE_NATIVE_FALLBACK"] == "1" diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_process_ascend_env.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_process_ascend_env.py new file mode 100644 index 00000000..2a454a01 --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_process_ascend_env.py @@ -0,0 +1,27 @@ +from test_pdf_npu_ocr_priority import _load_process_module + + +def test_process_ascend_env_includes_nnal_and_cann_variants(monkeypatch): + process = _load_process_module() + existing = "/tmp/existing_ld" + accepted = { + "/usr/local/Ascend/nnal/asdsip/8.5.1/lib", + "/usr/local/Ascend/nnal/atb/8.5.1/atb/cxx_abi_0/lib", + "/usr/local/Ascend/nnal/atb/latest/atb/cxx_abi_1/lib", + "/usr/local/Ascend/cann-8.5.0/lib64", + existing, + } + + monkeypatch.setenv("LD_LIBRARY_PATH", existing) + monkeypatch.setattr(process.os.path, "exists", lambda path: path in accepted) + + process._configure_ascend_runtime_environment() + + paths = process.os.environ["LD_LIBRARY_PATH"].split(":") + assert paths[:4] == [ + "/usr/local/Ascend/nnal/asdsip/8.5.1/lib", + "/usr/local/Ascend/nnal/atb/8.5.1/atb/cxx_abi_0/lib", + "/usr/local/Ascend/nnal/atb/latest/atb/cxx_abi_1/lib", + "/usr/local/Ascend/cann-8.5.0/lib64", + ] + assert paths[-1] == existing diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_require_npu_models.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_require_npu_models.py new file mode 100644 index 00000000..4b60b5bf --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_require_npu_models.py @@ -0,0 +1,229 @@ +from pathlib import Path + +import pytest + +from test_pdf_npu_ocr_priority import _Element, _load_process_module + + +def test_pdf_require_npu_models_rejects_missing_adapters(monkeypatch): + process = _load_process_module() + + monkeypatch.setattr(process, "partition_pdf", lambda **kwargs: [_Element("unused")]) + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: False) + + mapper = process.UnstructuredIOMapper(requireNpuModels=True) + + with pytest.raises(RuntimeError, match="NPU layout adapter is unavailable"): + mapper._extract_pdf(Path("sample.pdf")) + + +def test_pdf_require_npu_models_rejects_native_ocr_fallback(monkeypatch): + process = _load_process_module() + + monkeypatch.setattr(process, "partition_pdf", lambda **kwargs: [_Element("unused")]) + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) + process._NPU_OCR_ADAPTER_STATUS.update({"attempted": True, "npu": True, "ocr": True, "error": None}) + monkeypatch.setattr( + process, + "_get_ocr_runtime_status", + lambda: {"device": "npu", "native_only": True, "is_alive": False}, + ) + + mapper = process.UnstructuredIOMapper(requireNpuModels=True) + + with pytest.raises(RuntimeError, match="OCR NPU runtime is unavailable"): + mapper._extract_pdf(Path("sample.pdf")) + + +def test_docx_require_npu_models_uses_visual_npu_route(monkeypatch): + process = _load_process_module() + calls = [] + + monkeypatch.setattr(process, "_convert_office_to_pdf", lambda path: Path("converted.pdf")) + + def _extract_pdf(path): + calls.append(path) + return [{"index": 0, "category": "Title", "text": "converted"}], "pdf-npu-ocr-hi_res" + + mapper = process.UnstructuredIOMapper(requireNpuModels=True, enableDocxFastpath=True) + monkeypatch.setattr(mapper, "_extract_pdf", _extract_pdf) + + elements, mode = mapper._extract_elements(Path("sample.docx"), "docx") + + assert calls == [Path("converted.pdf")] + assert elements[0]["text"] == "converted" + assert mode == "docx-visual-pdf-npu-ocr-hi_res" + + +def test_docx_require_npu_models_rejects_non_npu_visual_route(monkeypatch): + process = _load_process_module() + + monkeypatch.setattr(process, "_convert_office_to_pdf", lambda path: Path("converted.pdf")) + + mapper = process.UnstructuredIOMapper(requireNpuModels=True, enableDocxFastpath=True) + monkeypatch.setattr( + mapper, + "_extract_pdf", + lambda path: ([_Element("fallback text")], "pdf-npu-ocr-fallback-fast"), + ) + + with pytest.raises(RuntimeError, match="DOCX visual NPU route did not use NPU OCR mode"): + mapper._extract_elements(Path("sample.docx"), "docx") + + +def test_docx_require_npu_models_rejects_npu_without_ocr(monkeypatch): + process = _load_process_module() + + monkeypatch.setattr(process, "_convert_office_to_pdf", lambda path: Path("converted.pdf")) + + mapper = process.UnstructuredIOMapper(requireNpuModels=True, enableDocxFastpath=True) + monkeypatch.setattr( + mapper, + "_extract_pdf", + lambda path: ([_Element("layout only")], "pdf-npu-hi_res"), + ) + + with pytest.raises(RuntimeError, match="DOCX visual NPU route did not use NPU OCR mode"): + mapper._extract_elements(Path("sample.docx"), "docx") + + +def test_docx_require_npu_models_fails_without_soffice(monkeypatch): + process = _load_process_module() + + monkeypatch.delenv("UNSTRUCTUREDIO_LIBREOFFICE_BIN", raising=False) + monkeypatch.setattr(process.shutil, "which", lambda name: None) + + with pytest.raises(RuntimeError, match="LibreOffice/soffice is required"): + process._convert_office_to_pdf(Path("sample.docx")) + + +def test_require_npu_models_disables_ocr_native_fallback(monkeypatch): + process = _load_process_module() + + monkeypatch.delenv("UNSTRUCTUREDIO_REQUIRE_NPU_MODELS", raising=False) + monkeypatch.delenv("OCR_ADAPTER_DISABLE_NATIVE_FALLBACK", raising=False) + + process.UnstructuredIOMapper(requireNpuModels=True) + + assert process.os.environ["UNSTRUCTUREDIO_REQUIRE_NPU_MODELS"] == "1" + assert process.os.environ["OCR_ADAPTER_DISABLE_NATIVE_FALLBACK"] == "1" + + +def test_strict_npu_ocr_runtime_requires_available_flag(): + process = _load_process_module() + + assert ( + process._is_strict_npu_ocr_runtime( + {"device": "npu", "native_only": False, "is_alive": True, "available": False} + ) + is False + ) + + +def test_apply_npu_ocr_adapters_prewarms_ocr_before_torch_npu(monkeypatch): + process = _load_process_module() + calls = [] + + class FakeNpuAdapter: + @staticmethod + def apply_patches(): + calls.append("npu") + + class FakeOcrAdapter: + @staticmethod + def apply_ocr_patch(): + calls.append("ocr_patch") + + @staticmethod + def get_ocr_runtime_status(): + calls.append("ocr_status") + return {"device": "npu", "native_only": False, "is_alive": True, "available": True} + + original_import = __import__ + + def fake_import(name, *args, **kwargs): + if name == "npu_adapter": + return FakeNpuAdapter + if name == "ocr_npu_adapter": + return FakeOcrAdapter + return original_import(name, *args, **kwargs) + + monkeypatch.setattr(process, "_configure_npu_ocr_environment", lambda: None) + monkeypatch.setattr(process.builtins, "__import__", fake_import) + process._NPU_OCR_ADAPTER_STATUS.update({"attempted": False, "npu": False, "ocr": False, "error": None}) + + assert process._apply_npu_ocr_adapters() is True + assert calls == ["ocr_patch", "ocr_status", "npu"] + + +def test_pdf_partition_is_imported_after_npu_adapters(monkeypatch): + process = _load_process_module() + calls = [] + + class FakePdfModule: + @staticmethod + def partition_pdf(**kwargs): + calls.append("partition_pdf") + return [ + _Element("long enough text from lazy pdf partition import path one"), + _Element("long enough text from lazy pdf partition import path two"), + _Element("long enough text from lazy pdf partition import path three"), + ] + + original_import = __import__ + + def fake_import(name, *args, **kwargs): + if name == "unstructured.partition.pdf": + calls.append("import_partition_pdf") + return FakePdfModule + return original_import(name, *args, **kwargs) + + monkeypatch.setattr(process, "partition_pdf", None) + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: calls.append("adapters") or True) + process._NPU_OCR_ADAPTER_STATUS.update({"attempted": True, "npu": True, "ocr": True, "error": None}) + monkeypatch.setattr( + process, + "_get_ocr_runtime_status", + lambda: {"device": "npu", "native_only": False, "is_alive": True, "available": True}, + ) + monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) + monkeypatch.setattr(process.builtins, "__import__", fake_import) + + mapper = process.UnstructuredIOMapper(requireNpuModels=True) + elements, mode = mapper._extract_pdf(Path("sample.pdf")) + + assert calls[:3] == ["adapters", "import_partition_pdf", "partition_pdf"] + assert mode == "pdf-npu-ocr-hi_res" + assert elements[0]["text"].startswith("long enough text") + + +def test_pdf_disables_table_structure_when_local_table_model_missing(monkeypatch): + process = _load_process_module() + seen_kwargs = [] + + monkeypatch.setattr(process, "_apply_npu_ocr_adapters", lambda: True) + process._NPU_OCR_ADAPTER_STATUS.update({"attempted": True, "npu": True, "ocr": True, "error": None}) + monkeypatch.setattr( + process, + "_get_ocr_runtime_status", + lambda: {"device": "npu", "native_only": False, "is_alive": True, "available": True}, + ) + monkeypatch.setattr(process.Path, "exists", lambda self: False) + monkeypatch.setattr(process, "_pdf_runtime_overrides", process.contextlib.nullcontext) + + def fake_partition_pdf(**kwargs): + seen_kwargs.append(kwargs) + return [ + _Element("long enough text from missing table model path one"), + _Element("long enough text from missing table model path two"), + _Element("long enough text from missing table model path three"), + ] + + monkeypatch.setattr(process, "partition_pdf", fake_partition_pdf) + + mapper = process.UnstructuredIOMapper(requireNpuModels=True, pdfInferTableStructure=True) + elements, mode = mapper._extract_pdf(Path("sample.pdf")) + + assert seen_kwargs[0]["infer_table_structure"] is False + assert mode == "pdf-npu-ocr-hi_res" + assert len(elements) == 3 diff --git a/runtime/ops/mapper/unstructuredio/operator_src/tests/test_table_transformer_npu.py b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_table_transformer_npu.py new file mode 100644 index 00000000..7b283ebd --- /dev/null +++ b/runtime/ops/mapper/unstructuredio/operator_src/tests/test_table_transformer_npu.py @@ -0,0 +1,162 @@ +import sys +import types + +from test_pdf_npu_ocr_priority import _load_process_module + + +def _install_fake_transformers(monkeypatch, calls): + transformers = types.ModuleType("transformers") + + class FakeProcessor: + @classmethod + def from_pretrained(cls, model_path, local_files_only=False): + calls.append(("processor", str(model_path), local_files_only)) + return cls() + + class FakeConfig: + last = None + + def __init__(self): + self.use_pretrained_backbone = True + FakeConfig.last = self + + @classmethod + def from_pretrained(cls, model_path, local_files_only=False): + calls.append(("config", str(model_path), local_files_only)) + return cls() + + class FakeModel: + def __init__(self, config): + calls.append(("model_init", config.use_pretrained_backbone)) + self.config = config + self.loaded = None + self.to_device = None + + def load_state_dict(self, state_dict, strict=False): + calls.append(("load_state_dict", state_dict, strict)) + self.loaded = state_dict + return [], [] + + def eval(self): + calls.append(("eval",)) + return self + + def to(self, device): + calls.append(("to", device)) + self.to_device = device + return self + + transformers.DetrImageProcessor = FakeProcessor + transformers.TableTransformerConfig = FakeConfig + transformers.TableTransformerForObjectDetection = FakeModel + monkeypatch.setitem(sys.modules, "transformers", transformers) + return FakeModel + + +def _install_fake_safetensors(monkeypatch, calls): + safetensors = types.ModuleType("safetensors") + safetensors_torch = types.ModuleType("safetensors.torch") + + def load_file(path, device="cpu"): + calls.append(("load_safetensors", str(path), device)) + return {"weight": "from-safetensors"} + + safetensors_torch.load_file = load_file + monkeypatch.setitem(sys.modules, "safetensors", safetensors) + monkeypatch.setitem(sys.modules, "safetensors.torch", safetensors_torch) + + +def test_table_transformer_loader_uses_config_state_dict_and_npu(monkeypatch, tmp_path): + process = _load_process_module() + calls = [] + model_cls = _install_fake_transformers(monkeypatch, calls) + _install_fake_safetensors(monkeypatch, calls) + (tmp_path / "model.safetensors").write_text("fake", encoding="utf-8") + + feature_extractor, model = process._load_local_table_transformer_model(tmp_path, "npu:0") + + assert feature_extractor is not None + assert isinstance(model, model_cls) + assert ("config", str(tmp_path), True) in calls + assert ("model_init", False) in calls + assert ("load_safetensors", str(tmp_path / "model.safetensors"), "cpu") in calls + assert ("load_state_dict", {"weight": "from-safetensors"}, False) in calls + assert ("to", "npu:0") in calls + assert model.to_device == "npu:0" + + +def test_pdf_runtime_overrides_initializes_table_agent_on_npu(monkeypatch, tmp_path): + process = _load_process_module() + calls = [] + _install_fake_transformers(monkeypatch, calls) + + unstructured_inference = types.ModuleType("unstructured_inference") + models_module = types.ModuleType("unstructured_inference.models") + tables_module = types.ModuleType("unstructured_inference.models.tables") + + class FakeTableAgent: + model = None + + class FakeTableTransformerModel: + initialize = lambda self, model=None, device="cpu": None + + tables_module.DEFAULT_MODEL = "old-model" + tables_module.tables_agent = FakeTableAgent() + tables_module.UnstructuredTableTransformerModel = FakeTableTransformerModel + tables_module.load_agent = lambda: None + models_module.tables = tables_module + unstructured_inference.models = models_module + monkeypatch.setitem(sys.modules, "unstructured_inference", unstructured_inference) + monkeypatch.setitem(sys.modules, "unstructured_inference.models", models_module) + monkeypatch.setitem(sys.modules, "unstructured_inference.models.tables", tables_module) + monkeypatch.setattr(process, "PDF_TABLE_MODEL_PATH", str(tmp_path)) + monkeypatch.setattr(process, "_select_table_transformer_device", lambda: "npu:0") + + def fake_loader(model_path, device): + calls.append(("loader", str(model_path), device)) + return "feature-extractor", "table-model" + + monkeypatch.setattr(process, "_load_local_table_transformer_model", fake_loader, raising=False) + + with process._pdf_runtime_overrides(): + tables_module.load_agent() + + assert ("loader", str(tmp_path), "npu:0") in calls + assert tables_module.tables_agent.device == "npu:0" + assert tables_module.tables_agent.feature_extractor == "feature-extractor" + assert tables_module.tables_agent.model == "table-model" + + +def test_pdf_runtime_overrides_rejects_cpu_table_device_in_strict_mode(monkeypatch, tmp_path): + process = _load_process_module() + + unstructured_inference = types.ModuleType("unstructured_inference") + models_module = types.ModuleType("unstructured_inference.models") + tables_module = types.ModuleType("unstructured_inference.models.tables") + + class FakeTableAgent: + model = None + + class FakeTableTransformerModel: + initialize = lambda self, model=None, device="cpu": None + + tables_module.DEFAULT_MODEL = "old-model" + tables_module.tables_agent = FakeTableAgent() + tables_module.UnstructuredTableTransformerModel = FakeTableTransformerModel + tables_module.load_agent = lambda: None + models_module.tables = tables_module + unstructured_inference.models = models_module + monkeypatch.setitem(sys.modules, "unstructured_inference", unstructured_inference) + monkeypatch.setitem(sys.modules, "unstructured_inference.models", models_module) + monkeypatch.setitem(sys.modules, "unstructured_inference.models.tables", tables_module) + monkeypatch.setattr(process, "PDF_TABLE_MODEL_PATH", str(tmp_path)) + monkeypatch.setattr(process, "_select_table_transformer_device", lambda: "cpu") + monkeypatch.setenv("UNSTRUCTUREDIO_REQUIRE_NPU_MODELS", "1") + + with process._pdf_runtime_overrides(): + try: + tables_module.load_agent() + except RuntimeError as exc: + assert "Table transformer NPU is required" in str(exc) + else: + raise AssertionError("strict mode accepted CPU table transformer device") diff --git a/runtime/ops/mapper/unstructuredio/test_cases/README.md b/runtime/ops/mapper/unstructuredio/test_cases/README.md index 38bec69b..1a4fb878 100644 --- a/runtime/ops/mapper/unstructuredio/test_cases/README.md +++ b/runtime/ops/mapper/unstructuredio/test_cases/README.md @@ -1,36 +1,34 @@ # unstructuredio 测试用例 -本目录提供公开可下载的 PDF 和 DOCX 样本,用于验收平台复测文档解析算子。 - -## 公开样本来源 - -- `example_input/attention_is_all_you_need.pdf` - arXiv 论文 *Attention Is All You Need*: - -- `example_input/bert_pretraining.pdf` - arXiv 论文 *BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding*: - -- `example_input/docx_corpus_sample_1.docx` - 公开 `docx-corpus` 样本: - - -- `example_input/docx_corpus_sample_2.docx` - 公开 `docx-corpus` 样本: - - - -## 平台测试步骤 - -1. 在 DataMate 算子市场上传 `../unstructuredio.zip`。 -2. 创建任务并上传 `example_input/` 下任一 PDF 或 DOCX 文件。 -3. 对 PDF 样本建议使用默认 `pdfStrategy=auto` 和 `pdfInferTableStructure=true`。 -4. 运行任务并下载输出 JSON。 - -## 检查项 - -- 输出文件非空,JSON 可解析。 -- 元素至少包含 `category`、`text`、`page_number`、`coordinates` 字段。 -- PDF 输出的 `page_number` 不应全部为 `1`。 -- PDF 标题、正文、表格标题附近文本应可读。 -- DOCX 输出的标题、段落、表格顺序应基本合理。 -- DOCX 的 `coordinates` 不应全部为空。 +本目录提供 4 个公开样本文档测试用例,用于在 DataMate 平台验证 unstructuredio 算子的 PDF/DOCX 解析能力。测试输入文件统一放在 `example_input` 目录,当前保留 2 个公开 PDF 样本和 2 个公开 DOCX 样本。 + +## 样本来源 + +- Attention Is All You Need PDF: https://arxiv.org/pdf/1706.03762 +- BERT PDF: https://arxiv.org/pdf/1810.04805 +- DOCX 示例文档来源: https://file-examples.com/index.php/sample-documents-download/sample-doc-download/ +- unstructured 开源项目: https://github.com/Unstructured-IO/unstructured + +## 文件说明 + +- `cases.json`: 4 个平台测试 case,覆盖 PDF 文本、PDF 坐标、PDF 表格、DOCX 段落、DOCX 表格和 metadata 输出检查。 +- `example_input/attention_is_all_you_need.pdf`: 公开论文 PDF 样本。 +- `example_input/bert_pretraining.pdf`: 公开论文 PDF 样本。 +- `example_input/docx_corpus_sample_1.docx`: 公开 DOCX 样本。 +- `example_input/docx_corpus_sample_2.docx`: 公开 DOCX 样本。 + +## 测试方法 + +1. 在 DataMate 平台上传 unstructuredio 算子。 +2. 选择 `example_input` 下的 PDF 或 DOCX 文件作为输入。 +3. 参数保持默认即可;如需验证表格结构,保持 `pdfInferTableStructure=true`。 +4. 执行后下载输出 JSON。 +5. 检查输出是否包含非空 elements、正确文件类型、PDF 页码与坐标、DOCX 文本和 metadata 信息。 + +## 通过标准 + +- 输出文件为合法 JSON。 +- `elements` 或等价结果数组非空。 +- PDF 样本应保留 `page_number` 和 `coordinates`。 +- DOCX 样本应保留段落、标题、表格等结构信息。 +- 表格类元素应尽量保留 `Table` 类型或 `text_as_html` 字段。 diff --git a/runtime/ops/mapper/unstructuredio/test_cases/cases.json b/runtime/ops/mapper/unstructuredio/test_cases/cases.json index 587438ad..a5e6e64d 100644 --- a/runtime/ops/mapper/unstructuredio/test_cases/cases.json +++ b/runtime/ops/mapper/unstructuredio/test_cases/cases.json @@ -1,74 +1,87 @@ [ { - "id": "pdf_arxiv_transformer", + "id": "unstructuredio_case_01", "operator": "unstructuredio", - "dataset": "arXiv", - "document_type": "pdf", - "sample_file": "example_input/attention_is_all_you_need.pdf", - "purpose": "验证学术 PDF 的多页解析、页码覆盖、坐标完整性与表格识别能力。", - "source_urls": [ - "https://arxiv.org/pdf/1706.03762.pdf", - "https://arxiv.org/abs/1706.03762" - ], + "dataset": "attention_is_all_you_need", + "file_type": "PDF", + "input_file": "example_input/attention_is_all_you_need.pdf", + "source_urls": ["https://arxiv.org/pdf/1706.03762"], + "purpose": "验证公开论文 PDF 的基础文本抽取、页码、坐标和表格结构输出。", + "run_parameters": { + "exportType": "json", + "pdfStrategy": "auto", + "pdfInferTableStructure": "true", + "suppressPdfNoise": "true" + }, "checks": [ - "输出 JSON 非空", - "page_number 不能全部为 1", - "coordinates 非空率 >= 90%", - "应包含正文块且存在表格相关内容" + "输出为合法 JSON", + "元素数组非空", + "PDF 元素包含 page_number", + "PDF 元素包含 coordinates", + "表格元素或 text_as_html 尽量保留" ] }, { - "id": "pdf_arxiv_bert", + "id": "unstructuredio_case_02", "operator": "unstructuredio", - "dataset": "arXiv", - "document_type": "pdf", - "sample_file": "example_input/bert_pretraining.pdf", - "purpose": "验证另一份公开论文 PDF 的通用解析稳定性,避免只对单篇样本适配。", - "source_urls": [ - "https://arxiv.org/pdf/1810.04805.pdf", - "https://arxiv.org/abs/1810.04805" - ], + "dataset": "bert_pretraining", + "file_type": "PDF", + "input_file": "example_input/bert_pretraining.pdf", + "source_urls": ["https://arxiv.org/pdf/1810.04805"], + "purpose": "验证公开论文 PDF 的多页正文、标题、页码和 metadata 输出。", + "run_parameters": { + "exportType": "json", + "pdfStrategy": "auto", + "pdfInferTableStructure": "true", + "suppressPdfNoise": "true" + }, "checks": [ - "输出 JSON 非空", - "应覆盖多页", - "主要标题与正文文本可读", - "coordinates 非空率 >= 90%" + "输出为合法 JSON", + "元素数组非空", + "识别标题或正文", + "多页内容 page_number 不应全部固定为 1", + "metadata 字段存在" ] }, { - "id": "docx_corpus_sample_1", + "id": "unstructuredio_case_03", "operator": "unstructuredio", - "dataset": "docx-corpus", - "document_type": "docx", - "sample_file": "example_input/docx_corpus_sample_1.docx", - "purpose": "验证 DOCX 原生链路的段落、表格顺序和 coordinates 补全能力。", - "source_urls": [ - "https://docxcorp.us/", - "https://docxcorp.us/documents/00042714bec87fe8097f604fdd230760c956aac77fa56fcd5bc5ffb68c60690a.docx" - ], + "dataset": "docx_corpus_sample_1", + "file_type": "DOCX", + "input_file": "example_input/docx_corpus_sample_1.docx", + "source_urls": ["https://file-examples.com/index.php/sample-documents-download/sample-doc-download/"], + "purpose": "验证公开 DOCX 样本的段落、标题和 metadata 输出。", + "run_parameters": { + "exportType": "json", + "enableDocxFastpath": "true", + "jsonIndent": "2" + }, "checks": [ - "输出 JSON 非空", - "标题、段落、表格顺序应基本合理", - "coordinates 不能全部为空", - "不应整份文档全部落在第一页" + "输出为合法 JSON", + "元素数组非空", + "DOCX 文本内容非空", + "metadata 保留文件类型信息" ] }, { - "id": "docx_corpus_sample_2", + "id": "unstructuredio_case_04", "operator": "unstructuredio", - "dataset": "docx-corpus", - "document_type": "docx", - "sample_file": "example_input/docx_corpus_sample_2.docx", - "purpose": "验证表格较多的 DOCX 样本在输出形态上仍与 unstructured 兼容。", - "source_urls": [ - "https://docxcorp.us/", - "https://docxcorp.us/documents/000e366a02330e96ce5e878a2c2ecceba7374715a1065a5ece914d024a25d951.docx" - ], + "dataset": "docx_corpus_sample_2", + "file_type": "DOCX", + "input_file": "example_input/docx_corpus_sample_2.docx", + "source_urls": ["https://file-examples.com/index.php/sample-documents-download/sample-doc-download/"], + "purpose": "验证公开 DOCX 样本的段落、表格和结构化输出。", + "run_parameters": { + "exportType": "json", + "enableDocxFastpath": "true", + "jsonIndent": "2" + }, "checks": [ - "输出 JSON 非空", - "表格附近文本不应全部退化为普通叙述块", - "coordinates 不能全部为空", - "文本顺序应与原文大体一致" + "输出为合法 JSON", + "元素数组非空", + "保留段落顺序", + "表格内容尽量保留为 Table 或 text_as_html", + "metadata 不应全部为 null" ] } ]