OpenMed 本地优先医疗 AI 实战指南:临床 NER 与 HIPAA PII 去标识化(Python / MLX / REST 全解析)
2026/9/19 1:53:04 网站建设 项目流程

OpenMed 本地优先医疗 AI 实战指南:临床 NER 与 HIPAA PII 去标识化(Python / MLX / REST 全解析)

【免费下载链接】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

OpenMed 是一个"本地优先"(local-first)的开源医疗 AI SDK:它把临床命名实体识别(clinical NER)与 HIPAA 级 PII 检测、去标识化完全放到你掌控的硬件上运行,患者数据不需要离开你的网络。本文以仓库根目录的 README.ar.md 为主体骨架,结合 openmed 源码包的真实实现,系统讲解从 30 秒快速上手、医学模型矩阵、PII 提取与去标识化、多语言支持,到 Apple Silicon(MLX)加速与 REST 服务部署的完整链路。读完后,你将能独立用 OpenMed 在 Python、Swift 与浏览器/服务端场景中完成临床文本的结构化抽取与隐私脱敏。


一、为什么选择 OpenMed:本地优先的部署边界

OpenMed 的核心立场是"你的数据、你的模型、你的硬件"。SDK 的核心运行时在所需模型组件就绪后完全本地处理,只有模型下载、远程适配、可选的遥测路径与用户自配的集成才会使用网络。README 中的部署边界表给出了清晰的职责划分:

部署考量OpenMed SDK 边界
核心运行时所需组件就绪后本地处理
可选网络路径下载、远程适配、遥测路径与集成可能使用网络
验证由部署方核验模型/数据的条款、隐私行为与临床适用性
接口Python、Swift、Android、浏览器与受支持的服务端

几个值得注意的定位要点(均来自 README.ar.md 与仓库现状):

  • 模型清单庞大且可审计:仓库根目录的 models.jsonl 收录了 2,266 条模型清单记录,可逐条核验模型、许可证与适用数据集(对应源码中的模型注册表 model_registry.py);
  • Safe Harbor 兼容的类别配置:可瞄准 18 类 HIPAA Safe Harbor 标识符,但部署仍需专家复核,仅使用 SDK 本身不构成 HIPAA 合规证明
  • 多后端执行路径:CPU / CUDA / MLX / 移动端 / 服务端 / 浏览器等转换器随环境与组件不同而各异;
  • Apache-2.0 开源 SDK:SDK 源码以 Apache-2.0 发布(见 LICENSE),模型与数据集的条款另行约定。

需要特别说明:README 强调"本地优先"并不等于"永远离线"——模型下载、远端适配等路径按各模型与数据集的条款使用网络,部署方应自行核验隐私与合规边界。


二、30 秒上手:analyze_text 临床实体抽取

README 给出了一个可以直接复制的 30 秒示例,使用默认疾病检测模型对一句临床文本做 NER:

from openmed import analyze_text result = analyze_text( "Patient started on imatinib for chronic myeloid leukemia.", model_name="disease_detection_superclinical", ) for entity in result.entities: print(f"{entity.label:<12} {entity.text:<28} {entity.confidence:.2f}") # DISEASE chronic myeloid leukemia 0.98 # DRUG imatinib 0.95

这段代码背后对应的是 openmed/init.py 中analyze_text的完整实现。从源码可以看到几个值得了解的默认行为:

  • 默认模型disease_detection_superclinical,可通过model_name或等价的model_id指定(两者同时传入会抛ValueError);
  • 句子检测默认开启sentence_detection=True),文本会先被切分为句子、再按“每块最多 6 句 / 每块最多max(480, max_length*4)字符”的规则分块推理,最后把分块预测的偏移量映射回原始文本,避免长文本被截断或跨句误标;
  • 聚合策略aggregation_strategy="simple"置信度阈值confidence_threshold=0.0(保留全部)、分组group_entities=False等都可按需调整;输出格式支持dict(默认)、jsonhtmlcsv
  • 可选assert_context=True为每个实体附加否定、不确定性、经历者(experiencer)与时态等临床上下文标签(对应 clinical/context.py 的实现);
  • model_name支持注册表键、Hugging Face 完整模型 ID、或本地模型目录三种形式。

离线 / 隔离环境:直接指向本地目录

README 专门给出了离线部署写法:把model_id指向一个本地模型目录,OpenMed 将直接本地加载,不访问 Hugging Face Hub

from openmed import OpenMedConfig, analyze_text result = analyze_text( "Patient presents with chronic myeloid leukemia and Type 2 diabetes.", model_id="./models/OpenMed-NER-DiseaseDetect-SuperClinical-434M", config=OpenMedConfig(device="cpu"), )

OpenMedConfig负责后端/设备等运行时配置(源码见 core/config.py 及openmed.core模块导出),离线场景下配合device="cpu"即可完全本地推理。


三、快速开始:三种安装方式

README 的安装命令按运行形态分为三档:

# Core + Hugging Face runtime (Linux, macOS, Windows; CPU or CUDA) pip install --upgrade "openmed[hf]" # Add the REST service pip install --upgrade "openmed[hf,service]" # Apple Silicon acceleration (MLX) pip install --upgrade "openmed[mlx]"
  • 基础包openmed[hf]提供 Python 运行时(CPU/CUDA),跨 Linux、macOS、Windows;
  • 追加serviceextra 后可使用uvicorn启动 REST 服务(见下文第四节);
  • 在 Apple Silicon 上追加mlxextra 即可启用 MLX 加速运行时(详见第九节)。

当前仓库版本号为 2.3.0(见 openmed/about.py),需要 Python 3.10+。SDK 源码按 Apache-2.0 发布。


四、三种接口形态:Python、REST、批量

README 用三栏对照展示了 OpenMed 的三种主流调用方式,本文分别展开并补充源码细节。

1. Python 接口

from openmed import analyze_text analyze_text( "Patient received 75mg " "clopidogrel for NSTEMI.", model_name= "pharma_detection_superclinical", )

使用pharma_detection_superclinical(药物/治疗检测)时,会识别DRUGMEDICATIONTREATMENT等实体。

2. REST 服务

uvicorn openmed.service.app:app \ --host 0.0.0.0 --port 8080

核心端点(README 列举,且均能在 openmed/service/app.py 中找到对应路由实现):

端点方法说明
/healthGET健康检查(另有/livez/readyz
/analyzePOST临床实体分析
/pii/extractPOSTPII 实体提取
/pii/deidentifyPOSTPII 去标识化

/pii/extract/pii/deidentify的实现(openmed/service/app.py)会携带请求级追踪标签(端点、输入长度、模型名),并支持批处理、超时控制与请求合并(coalescing),服务本身是 Docker 友好的 FastAPI 应用,带请求校验、共享管线预加载与统一错误包装。

3. 批量处理(BatchProcessor)

from openmed import BatchProcessor p = BatchProcessor( model_name= "disease_detection_superclinical", group_entities=True, ) p.process_texts([...])

BatchProcessor的源码位于 openmed/processing/batch.py,支持三种operationanalyze_text(默认)、extract_piideidentify。默认按每批 8 篇文档处理,置信度阈值随操作类型自动对齐(analyze_text0.0、extract_pii0.5、deidentify0.7),支持continue_on_error、持久化 checkpoint、进度跟踪与错误汇总,适合批量脱敏数据集。


五、医学 NER 模型矩阵

README 给出了一个精选的医学 NER 模型清单(完整目录见仓库 models.jsonl 与模型注册表 model_registry.py):

模型专长实体类型大小
disease_detection_superclinical疾病与状况DISEASE, CONDITION, DIAGNOSIS434M
pharma_detection_superclinical药物与治疗DRUG, MEDICATION, TREATMENT434M
pii_superclinical_largePII 与去标识化NAME, DATE, SSN, PHONE, EMAIL, ADDRESS434M
anatomy_detection_electramed解剖与身体部位ANATOMY, ORGAN, BODY_PART109M
gene_detection_genecorpus基因与蛋白质GENE, PROTEIN109M

源码佐证:在 model_registry.py 中可以看到这些短名(registry key)与完整模型 ID 的别名映射,例如:

  • disease_detection_superclinicalOpenMed/OpenMed-NER-DiseaseDetect-SuperClinical-434M
  • pharma_detection_superclinicalOpenMed/OpenMed-NER-PharmaDetect-SuperClinical-434M
  • anatomy_detection_electramedOpenMed/OpenMed-NER-AnatomyDetect-ElectraMed-109M

也就是说,你既可以用短名让 OpenMed 自动解析,也可以直接用完整模型 ID 或本地目录路径(见第二节离线示例)。除此之外注册表中还有肿瘤、病理、血癌、化学物、物种、蛋白质等更多专业模型,可调用get_models_by_category()get_model_info()openmed.core.model_registry导出)浏览。


六、隐私核心:PII 检测与去标识化

这是 OpenMed 的招牌能力。README 给出的完整示例:

from openmed import extract_pii, deidentify text = "Patient: John Doe, DOB: 01/15/1970, SSN: 123-45-6789" # Extract PII with smart merging (prevents tokenization fragmentation) result = extract_pii(text, model_name="pii_superclinical_large", use_smart_merging=True) # De-identify with the method you need deidentify(text, method="mask") # [NAME], [DATE] deidentify(text, method="replace") # Faker-backed, locale-aware, format-preserving fakes deidentify(text, method="hash") # Cryptographic hashing deidentify(text, method="shift_dates", date_shift_days=180)

extract_pii:智能合并

extract_pii的签名与实现位于 openmed/core/pii.py。关键参数包括:

  • model_name:PII 检测模型(默认按lang自动选择语言合适的模型);
  • confidence_threshold:默认 0.5;
  • use_smart_merging:默认True,用正则识别语义单元(日期、SSN、电话等),把模型因分词而切碎的结果合并回完整实体,例如01/15/1970不会被拆成01/15/1970
  • lang:ISO 639-1 语言码,决定默认模型与正则模式;
  • normalize_accents:去除变音符号后再推理(默认对西班牙语自动开启),实体偏移仍指向原文;
  • custom_recognizer:自定义 deny-list / allow-list 识别器,命中带custom:deny来源标记;
  • budget:可选的单请求墙钟时间与输入字符预算(超长输入在推理前直接拒绝)。

deidentify:七种脱敏策略

deidentify(openmed/core/pii.py)实现了比 README 更完整的策略集合,默认confidence_threshold=0.7(更保守、更安全),并默认执行use_safety_sweep=True(去标识化前再跑一遍确定性结构化标识符扫描):

方法行为
mask替换为占位符,如[NAME][EMAIL]
aadhaar_mask将 Aadhaar 渲染为XXXX XXXX NNNN(UIDAI 掩码形式),其余实体用普通占位符
remove完全删除 PII 文本
replace用逼真但虚构的数据替换(Faker 驱动、区域感知、保格式)
hash用一致的哈希值替换,便于实体关联
format_preserve保留形状与分隔符的合成结构化标识符,不支持的标签走掩码
shift_dates按随机偏移平移日期并保持时间间隔

其他值得注意的参数:keep_year(日期保留年份)、patient_key+date_shift_secret(HMAC 派生确定性的日期平移偏移,保证跨会话稳定且原始 key 不被记录/持久化)、consistent=True(同一输入生成同一替代身份)、seed(跨运行可复现)、locale(Faker 区域覆盖,如pt_BRen_GB)、policy(策略配置档)、audit=True(返回确定性的AuditReport审计报告)。

保真且校验有效的虚构标识符

README 特别指出replace方法背后的 Faker 提供者支持带校验和的临床标识符:CPF、CNPJ、BSN、NIR、Codice Fiscale、NIE、Aadhaar、Steuer-ID、NPI。这在源码 openmed/core/anonymizer/providers/clinical_ids.py 中有完整实现,例如:

  • 巴西 CPF/CNPJ、荷兰 BSN、法国 NIR、意大利 Codice Fiscale 等均生成通过各自校验规则的合法格式;
  • Aadhaar 使用 Verhoeff 校验和生成合法 12 位号码(format_preserve.py 还提供 UIDAI 掩码渲染);
  • 德国 Steuer-ID 与 10 位美国 NPI 也都有专门的 provider(GermanSteuerIdProviderNPIProvider)。

也就是说,method="replace"产出的替代值不只是"像",而是真正满足校验逻辑的合成数据,可直接用于下游测试与二次加工。

HIPAA 边界声明

README 明确声明:Safe Harbor 兼容类别与可配置阈值是实施辅助工具,部署仍需专家复核,仅使用 SDK 不构成 HIPAA 合规证明。文章写作时请务必在系统设计中保留这一复核环节。


七、Privacy Filter 模型家族

README 用<details>折叠块介绍了 Privacy Filter 家族:三个模型共享同一种架构(gpt-oss 风格的 Sparse-MoE 转换器,带局部注意力、sink tokens、RoPE+YaRN,tiktokeno200k_base分词),只训练数据不同;它们都走同一个extract_pii()/deidentify()接口,只改model_name参数:

变体PyTorch (CPU + CUDA)MLX (Apple Silicon)MLX 8-bit
OpenAI Privacy Filteropenai/privacy-filterOpenMed/privacy-filter-mlx…-mlx-8bit
Nemotron-PII fine-tuneOpenMed/privacy-filter-nemotron…-nemotron-mlx…-nemotron-mlx-8bit
OpenMed MultilingualOpenMed/privacy-filter-multilingual…-multilingual-mlx…-multilingual-mlx-8bit
from openmed import extract_pii text = "Patient Sarah Connor (DOB: 03/15/1985) at MRN 4471882." extract_pii(text, model_name="openai/privacy-filter") # PyTorch baseline extract_pii(text, model_name="OpenMed/privacy-filter-nemotron") # same code, different weights extract_pii(text, model_name="OpenMed/privacy-filter-mlx") # Apple Silicon (MLX)

一个模型名,全平台运行:在非 Apple Silicon 主机上,MLX 模型名会自动回退到对应的 PyTorch checkpoint(并给出一次性警告)——你只需写一个模型名,就能在任何地方运行。README 中的演示 GIF(docs/brand/openmed-pii-demo.gif)展示的正是 Nemotron Privacy Filter 在本地实时隐藏临床出院报告中的姓名、地址、标识符与账单数据。

实时去标识化:Privacy Filter 家族模型在设备本地隐藏临床文档中的姓名、地址、标识符与账单信息(图中数值均为合成数据)。


八、多语言 PII:36 条受支持路径 / 33 个模型支持的语种

README 声明多语言 PII 提取与去标识化覆盖enfrdeitesnlhiteptarjatr,模型注册表总计 33 个模型支持的语种、36 条受支持路径(对应openmed.core.pii_i18nSUPPORTED_LANGUAGESDEFAULT_PII_MODELS导出)。用法是给extract_piilang参数:

python -c "from openmed import extract_pii; print([(e.label, e.text) for e in extract_pii('Dr. Pedro Almeida, CPF: 123.456.789-09, email: pedro@hospital.pt', lang='pt').entities])"

README 还为葡萄牙语、荷兰语、印地语、阿拉伯语、日语、土耳其语各给出一个完整示例:

from openmed import extract_pii portuguese = extract_pii("Paciente: Pedro Almeida, CPF: 123.456.789-09, telefone: +351 912 345 678", lang="pt", use_smart_merging=True) dutch = extract_pii("Patiënt: Eva de Vries, BSN: 123456782, telefoon: +31 6 12345678", lang="nl", use_smart_merging=True) hindi = extract_pii("रोगी: अनीता शर्मा, फोन: +91 9876543210, पता: नई दिल्ली 110001", lang="hi", use_smart_merging=True) arabic = extract_pii("المريضة ليلى حسن، الهاتف +20 10 1234 5678، الرقم القومي 29801011234567.", lang="ar", use_smart_merging=True) japanese = extract_pii("患者 佐藤 花子、電話 +81 90 1234 5678、マイナンバー 1234 5678 9012.", lang="ja", use_smart_merging=True) turkish = extract_pii("Hasta Ayşe Yılmaz, telefon +90 532 123 45 67, TCKN 10000000146.", lang="tr", use_smart_merging=True) for r in (portuguese, dutch, hindi, arabic, japanese, turkish): print([(e.label, e.text) for e in r.entities])

从源码看,多语言能力不仅是"换模型"这么简单:lang会同时驱动默认模型选择、正则模式库与 Faker 替代数据区域deidentifymethod="replace"会依据lang推导 Faker locale(如pt_BRen_GB);对印地语/泰卢固语等混合文字场景,还内置了脚本感知的印度临床路由(abdmcode_mixed等参数,见 core/pii.py 与 core/anonymizer 目录)。


九、在 Apple 上运行:MLX、OpenMedKit 与 Swift

在受支持的 Apple 硬件上,OpenMed 可用MLXOpenMedKit(Swift 原生 SDK,源码见 swift/OpenMedKit)实现本地处理。模型获取与用户自配的远端集成仍是独立的网络边界。README 给出了 Swift 包依赖写法(以 OpenMedKit 当前版本为准,示例中为 2.3.0):

// Add OpenMedKit to your app dependencies: [ .package(url: "https://github.com/maziyarpanahi/openmed.git", from: "2.3.0"), ]

关键能力:

  • MLX 运行时:用于 PII token 分类、Privacy Filter 家族与 GLiNER 家族的实验性 zero-shot 任务,另有 CoreML 回退路径;
  • 一个模型名、全平台:非 Apple 硬件上 MLX 模型名自动回退到对应 PyTorch checkpoint;
  • Apple Silicon 上的 Pythonpip install --upgrade "openmed[mlx]"即可。

进一步阅读:MLX 后端说明、Swift OpenMedKit 指南、CoreML 导出。仓库还提供开箱即用的 Swift 演示工程 swift/OpenMedDemo 与 swift/OpenMedScanDemo,以及 Android / ONNX Runtime Mobile(docs/export-onnx-android.md)与浏览器 / Transformers.js(docs/export-transformersjs.md)的导出路线。


十、REST API 实战:部署与调用

README 给出了 REST 服务的最小化部署路径:

pip install --upgrade "openmed[hf,service]" uvicorn openmed.service.app:app --host 0.0.0.0 --port 8080 # or with Docker docker build -t openmed:local . docker run --rm -p 8080:8080 -e OPENMED_PROFILE=prod openmed:local

一个多语言 PII 提取的 curl 示例(README 原文,lang="es"西班牙语场景):

curl -X POST http://127.0.0.1:8080/pii/extract \ -H "Content-Type: application/json" \ -d '{"text":"Paciente: Maria Garcia, DNI: 12345678Z","lang":"es"}'

服务端实现(openmed/service/app.py)是 FastAPI 应用:除上文端点外还有/models/loaded/models/unload/pii/extract/stream/pii/deidentify/stream等流式与运维端点,请求支持批处理提交、优先级与超时。完整的服务端指南见 docs/rest-service.md,Docker 部署参考仓库根目录 Dockerfile 与 docker-compose.yml。


十一、工作原理

README 给出了一个简洁的端到端流程图(Mermaid):

一条输入文本在 OpenMed 中会同时产出三类结果:医学实体(NER)、PII 检测结果、以及去标识化后的安全文本——这正是"提取 + 脱敏"一体的工作方式,也是第一节部署边界表中"本地处理"的具体落点。


十二、进一步探索

README 还提供了丰富的仓库内资源入口(以下链接均已转换为仓库根目录相对路径):

主题入口
入门与 APIdocs/index.md · docs/analyze-text.md
模型注册表models.jsonl · docs/model-registry.md
PII 完整教程examples/notebooks/PII_Detection_Complete_Guide.ipynb
去标识化docs/anonymization.md
智能合并docs/pii-smart-merging.md
批量处理docs/batch-processing.md
配置(Profiles)docs/profiles.md
REST 服务docs/rest-service.md
MLX 后端docs/mlx-backend.md

贡献与许可

欢迎通过 issue 与 pull request 参与贡献(见 CONTRIBUTING.md 与 docs/contributing.md);README 特别欢迎社区完成各语言 README 的翻译补全。OpenMed SDK 源码以 Apache-2.0 许可证发布(LICENSE),模型与数据集的条款另行约定。

引用

如果 OpenMed 对你的研究工作有帮助,可参考以下 BibTeX 引用(完整论文信息见仓库根 README.md):

@misc{panahi2025openmedneropensourcedomainadapted, title={OpenMed NER: Open-Source, Domain-Adapted State-of-the-Art Transformers for Biomedical NER Across 12 Public Datasets}, author={Maziyar Panahi}, year={2025}, eprint={2508.01630}, archivePrefix={arXiv}, primaryClass={cs.CL}, }

结语

OpenMed 的价值在于把"临床 NER + PII 去标识化"这条通常依赖云端的链路完整搬回本地:一份输入文本,同时产出医学实体、PII 检测与脱敏结果;一套模型名,在 PyTorch、MLX、Android 与浏览器之间自由切换;一组精心设计的脱敏策略,让替代值既逼真又满足校验规则。无论是快速原型(analyze_text)、批量数据集脱敏(BatchProcessor)、Apple 端本地运行(MLX / OpenMedKit),还是服务化部署(REST / Docker),你都可以从本文的示例与源码索引出发,直接在生产场景中落地。请始终记得:工具辅助实现不等于合规本身,部署前的专家复核与数据条款核验不可省略。

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询