OpenMed 中/印地语/泰米尔语去标识吞吐量基准与发布门禁:i18n-throughput 从实测到基线守护的完整实践
【免费下载链接】openmedLocal-first healthcare AI: clinical NER & HIPAA PII de-identification that runs 100% on-device. 2,200+ medical models, 21 languages, Apple MLX + Python, no cloud, no patient data leaving your network. Apache-2.0项目地址: https://gitcode.com/GitHub_Trending/ope/openmed
本指南围绕仓库文档 docs/benchmarks/i18n-throughput.md 展开,系统讲解 OpenMed 如何为中文(zh)、印地语(hi)、泰米尔语(ta)三类非拉丁文字建立稳态吞吐量基准(segmentation 字符/秒 与deidentify()脱敏跨度/秒),并通过20% 回归阈值门禁把多语言性能退化拦截在发布之前。读完本文,你将掌握:如何本地复现该基准、理解合成语料的确定性生成与哈希校验机制、读懂 gates/baseline.json 中基线条目的全部字段,以及如何在评审制流程下安全刷新基线与再生成语料。
为什么需要 i18n 吞吐量门禁
OpenMed 是本地优先(local-first)的医疗 AI 脱敏引擎,宣称支持 21 种语言与 2,200+ 医疗模型。在"全部本地运行、患者数据不出网络"的前提下,多语言文字处理性能直接决定端侧体验:中文需要分词器(segmenter),印地语/泰米尔语这类 Indic 文字需要处理连字簇(grapheme cluster),而脱敏管线还要在这些文本上运行正则与模式检测器。
为避免性能回归在用户设备上才暴露,OpenMed 在发布候选(release candidate)阶段设置了两类稳态测量,见 i18n-throughput.md:
- 分词吞吐量:
segmentation_chars_per_second(每秒处理字符数); - 端到端脱敏吞吐量:
deidentify_spans_per_second(每秒产出去标识化跨度数)。
测量覆盖三个提交到仓库的全合成语料:中文、印地语、泰米尔语,每个语料至少 100,000 字符。值得注意的是,该基准刻意运行在pattern-only 模式——不加载任何模型权重、不访问网络,只测分词器与确定性模式检测器的纯本地路径,因此结果稳定、可复现、适合作为发布门禁,而非模型推理性能评估。
指标定义与源码实现
基准的完整实现在 openmed/eval/i18n_throughput.py。其核心常量明确了测试口径:
I18N_THROUGHPUT_LANGUAGES = ("zh", "hi", "ta") I18N_THROUGHPUT_MIN_CHARS = 100_000 # 每个语料最小字符数 I18N_THROUGHPUT_MAX_SECONDS = 300.0 # 完整基准 5 分钟时限 I18N_THROUGHPUT_DEID_CHUNK_CHARS = 4_096 # 脱敏分块大小benchmark_language()对每个语言执行两类测量:
- 冷启动(cold start):在第一个"按换行对齐"的分块(
_iter_corpus_chunks,默认 4096 字符)上记录首次调用延迟,中文侧包含词典初始化耗时,记为segmentation_cold_start_ms与deidentify_cold_start_ms; - 稳态(steady state):对完整语料运行
iterations轮(默认 1),计算segmentation_chars_per_second = 总字符数 × 迭代数 / 耗时与deidentify_spans_per_second = 总跨度数 / 耗时。
不同语言的分词后端在run_benchmark()的backend字段中明示:
"backend": { "segmentation": { "zh": "jieba", "hi": "grapheme-safe-indic", "ta": "grapheme-safe-indic", }, "deidentify": "pattern-only", "model_weights_required": False, }- 中文走
create_chinese_segmenter("jieba"),工厂函数位于 openmed/processing/zh_segmentation.py,支持jieba/pkuseg/hanlp三种后端(本基准固定jieba); - 印地语与泰米尔语走
indic_word_tokenize(),位于 openmed/processing/tokenization.py,按 Unicode 字素簇(grapheme cluster)分组字母、保留数字内的日期/号码分隔符、标点独立成 token,保证 Span 索引与原文严格对齐,绝不切断 Indic 连字。
Pattern-only 脱敏路径:零模型、零网络
基准刻意使用_PatternOnlyLoader适配器(同文件第 47–69 行),它故意不产生任何模型预测:
class _PatternOnlyLoader: """Model-loader adapter that deliberately produces no model predictions.""" def create_pipeline(self, model_name, **kwargs): def empty_pipeline(text, **call_kwargs): if isinstance(text, list): return [[] for _ in text] return [] return empty_pipeline_deidentifier_factory随后以model_name="pattern-only"调用 openmed.core.pii 的 deidentify(method="mask"、use_smart_merging=False、use_safety_sweep=True),并按 4096 字符的换行对齐分块处理语料——这样句子切分复杂度不会随语料规模呈二次增长。报告只统计len(result.pii_entities),即被识别的跨度数量。
合成语料:确定性、可复现、无真实 PHI
语料由generate_synthetic_corpus()(i18n_throughput.py)生成,关键设计点:
| 维度 | 取值 |
|---|---|
| 生成器 | Faker,按语言设置 locale:zh_CN/hi_IN/ta_IN |
| 种子 | 每语言固定:zh=698001、hi=698002、ta=698003 |
| 访问日期窗口 | 固定为2021-07-23至2026-07-23(_VISIT_DATE_START/_VISIT_DATE_END),与日历无关,保证跨年份稳定 |
| 最小规模 | 至少 100,000 个字符 |
| 记录结构 | 中文含合成病例前缀 + 患者姓名、身份证号、手机号、就诊日期、地址;印地语/泰米尔语含कृत्रिम मामला/செயற்கை பதிவு前缀 + 姓名、Aadhaar、电话、日期、地址,全部带"纯合成测试数据"声明 |
| 元数据 | schema_version、Faker 版本与 locale、seed、char_count、record_count、全文sha256 |
生成的 JSON fixture 提交在 tests/fixtures/i18n/zh_throughput.json、tests/fixtures/i18n/hi_throughput.json、tests/fixtures/i18n/ta_throughput.json。
load_synthetic_corpus()在加载时会做严格校验:schema 版本、语言标签、synthetic=True、generated_only=True、生成器必须是 Faker、字符数不小于 100,000、char_count与sha256必须与文本匹配——任何一项不符直接抛ValueError,从机制上防止真实 PHI 混入或语料被篡改。基准报告只输出聚合指标、语料规模与哈希,绝不复制 fixture 文本或检测到的表面(surface)内容,这也与仓库整体的"no raw PHI logging"安全基线一致。
本地复现:从安装到出报告
按 i18n-throughput.md 的"Run locally"章节,完整命令如下:
# 1. 安装开发与语言相关 extras(jieba 中文分词、Indic 语言依赖) uv sync --extra dev --extra zh --extra indic # 2. 运行完整基准,产出机器可读 JSON 报告 .venv/bin/python -m openmed.eval.i18n_throughput \ --output i18n-throughput-report.json # 3. 用候选报告对基线执行发布门禁判定 .venv/bin/python -m openmed.eval.release_gates \ --throughput-candidate i18n-throughput-report.json \ --baseline-store gates/baseline.json \ --output i18n-throughput-gate.jsonopenmed.eval.i18n_throughput模块的 CLI(main(),i18n_throughput.py)还支持以下参数,便于定向测试:
| 参数 | 默认值 | 说明 |
|---|---|---|
--fixtures-dir | tests/fixtures/i18n | 语料 JSON 所在目录 |
--language | 全部(zh/hi/ta) | 可重复传入,只跑指定语言 |
--iterations | 1 | 每个操作/语言的稳态迭代次数 |
--max-duration-seconds | 300.0 | 超出该时限整个基准直接失败 |
--output | 无(打印 stdout) | 机器可读报告输出路径 |
整个基准被I18N_THROUGHPUT_MAX_SECONDS = 300.0硬性约束:run_benchmark()在循环结束后检查duration_seconds >= max_duration_seconds则抛出RuntimeError。报告结构包含artifact_type: "openmed.eval.i18n_throughput"、generated_at(UTC)、backend、python、platform、每个语料的corpora摘要(路径、seed、char_count、sha256)与languages指标明细。
门禁判定逻辑:20% 回归阈值
门禁核心是evaluate_i18n_throughput_gate()(release_gates.py),判定规则:
- 基线存储校验:先对
gates/baseline.json执行validate_baseline_store,非法即判定失败; - 报告类型校验:候选
artifact_type必须是openmed.eval.i18n_throughput,否则拒绝; - 逐语言比对:对 zh/hi/ta 三个语言,按
baseline_key("i18n-throughput", language, "pattern-only")查找基线条目,校验regression_threshold必须精确等于0.2(I18N_THROUGHPUT_REGRESSION_THRESHOLD = 0.20,release_gates.py); - 双指标判定:对
segmentation_chars_per_second与deidentify_spans_per_second两个指标,计算minimum = baseline * (1 - 0.2),任一指标低于该下限即记录 violation(含 baseline、observed、minimum、drop_fraction),并输出throughput regression: <详情>作为失败原因; - 决策输出:
_run_i18n_throughput_gate_cli()(release_gates.py)打包为openmed.eval.i18n_throughput_gate报告,passed=True时decision=RELEASABLE(退出码 0),否则QUARANTINED(退出码 1)。
一个重要设计决策:冷启动指标(cold start)不参与门禁。函数 docstring 明确说明——进程与文件系统缓存状态使冷启动延迟不适合作为稳定的发布阈值,它只在报告中可见,供人工排查。
基线数据解读:当前各语言稳态值
gates/baseline.json 中三个i18n-throughput::<lang>::pattern-only条目记录了当前基准值(GitHub Hosted Ubuntu x86_64 runner 上六次连续运行的中位数,更新于 2026-08-12):
| 语言 (tier) | segmentation_chars_per_second | deidentify_spans_per_second |
|---|---|---|
| zh | 320,459.236 | 624.1955 |
| hi | 135,093.3405 | 37.4975 |
| ta | 138,784.6725 | 52.22 |
每个条目的元数据还记录了校准方式:
{ "family": "i18n-throughput", "format": "pattern-only", "tier": "zh", "metadata": { "benchmark_schema_version": 1, "calibration_artifact_set_sha256": "sha256:5c794707...", "calibration_method": "median", "calibration_run_ids": [31149389732, 31239595555, 31295013051, 31357054005, 31459311593, 31565474523], "calibration_sample_count": 6, "corpus_sha256": "sha256:eb9a1ff6...", "iterations": 1, "recorded_platform": "GitHub-hosted Ubuntu x86_64", "regression_threshold": 0.2 }, "metrics": { ... }, "reproducibility_hash": "sha256:5c794707...", "updated_at": "2026-08-12T00:00:00+00:00" }其中reproducibility_hash与calibration_artifact_set_sha256相同,其定义为按 run_id 排序的{run_id, report}对象列表的紧凑、按键排序 JSON 的 SHA-256,评审者可以凭命名的 workflow 构件复算验证。
基线刷新:评审制、不自动更新
文档强调:基线永远不会自动更新。发布工作流跑在 GitHub 托管的 Ubuntu x86_64 runner 上,因此提交的基线必须来自同一 runner 类别(而非开发者工作站),否则跨硬件比较没有意义。当前值取自六次连续 hosted 运行的中位数,每次条目标注运行 ID 与聚合校准哈希。
刷新基线只能通过评审过的 Pull Request完成,流程如下(i18n-throughput.md 原文五步):
- 从指定的 GitHub Hosted Ubuntu x86_64 workflow 收集至少六个完成的基准构件;
- 排查双峰(bimodal)或不稳定结果,对每个稳态指标取中位数而非单次快跑值;
- 仅更新
gates/baseline.json中的六个稳态指标及其测量元数据(来源运行 ID、样本数、聚合可复现哈希); - 将 JSON diff 与基准报告一起评审,不允许仅为了让门禁通过而接受无法解释的更低基线;
- 合并前运行吞吐量门禁与完整测试套件。
语料再生成同样是评审制
.venv/bin/python scripts/benchmarks/generate_i18n_throughput_fixtures.py该脚本(generate_i18n_throughput_fixtures.py)支持--output-dir与--target-chars两个参数,内部复用write_synthetic_corpora()。提交再生成的语料前,需评审 fixture 元数据、哈希、规模,并确认所有测试均基于合成数据。
测试验证:门禁行为有据可查
openmed/eval/i18n_throughput.py 的行为由 tests/unit/eval/test_i18n_throughput.py 覆盖,关键断言包括:
- 语料合法性:每个提交语料 ≥100,000 字符、
synthetic=True、generated_only=True、生成器为 Faker、哈希以sha256:开头(test_committed_corpora_are_large_deterministic_faker_fixtures); - 指标完备性:冷启动与稳态四项指标均非负且稳态值大于 0(
test_benchmark_emits_cold_start_and_steady_state_metrics); - 访问日期窗口固定:用 StubFaker 验证
date_between的窗口精确等于2021-07-23到2026-07-23,且记录中出现2021-07-23(test_synthetic_records_use_a_calendar_independent_visit_window); - 阈值边界:候选值恰好为基线的 80%(即恰好允许 20% 下降)时门禁通过(
test_throughput_gate_allows_exactly_twenty_percent_drop); - 基线一致性:提交的
gates/baseline.json与 hosted runner 校准值匹配(test_committed_baseline_matches_hosted_runner_calibration)。
这些测试确保"基准可复现、门禁可判定、基线可审计"三项承诺不会在后续改动中被破坏。
小结:一条从实测到发布的完整守护链
OpenMed 的 i18n 吞吐量基准是一条设计严谨的发布守护链:确定性 Faker 合成语料(含哈希校验)→ 零模型 pattern-only 测量(分词/脱敏双指标)→ 5 分钟时限约束 → 20% 回归阈值门禁(RELEASABLE / QUARANTINED)→ 评审制基线刷新。它既保证了中、印地、泰米尔三种非拉丁文字在端侧的核心路径不会静默劣化,又通过"仅提交聚合指标与哈希、绝不携带 PHI"的报告格式守住隐私底线。
如果你要为本仓库做性能回归排查或发布前验证,推荐按以下顺序行动:先跑uv sync --extra dev --extra zh --extra indic复现基准,再以--language定向复测可疑语言,最后用release_gates --throughput-candidate对照 gates/baseline.json 判定是否可发布;任何基线刷新都必须走评审制 PR,并保留六次 hosted 运行的中位数证据。
【免费下载链接】openmedLocal-first healthcare AI: clinical NER & HIPAA PII de-identification that runs 100% on-device. 2,200+ medical models, 21 languages, Apple MLX + Python, no cloud, no patient data leaving your network. Apache-2.0项目地址: https://gitcode.com/GitHub_Trending/ope/openmed
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考