在你掌控的硬件上,将临床文本转化为结构化、去标识化的洞见。
OpenMed 的核心本地运行时会在所需模型制品就绪后执行抽取和去标识化。模型下载、远程提供商适配器、启用遥测的路径及用户配置的集成可能使用网络;请核查每个模型和数据集的条款。
PyPI package · Python 3.10+ · Model catalog · Research paper · Apache-2.0 SDK source
OpenMedKit · Apple Silicon / MLX · Android / ONNX Runtime Mobile · Browser / Transformers.js · Documentation
2,266 条清单记录 · 35 种模型支持的 PII 语言 · Apache-2.0 SDK
English · 简体中文 · Español · Français · Deutsch · Italiano · Português · Nederlands · العربية · हिन्दी · తెలుగు · 日本語 · Türkçe · فارسی · Kiswahili
此 iPhone 示例会在所需模型制品就绪后使用 OpenMed 的本地运行时:
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临床 NER 模型会在所需制品就绪后使用本地运行时。
在源码检出目录中运行仅使用 CPU 的合成数据接口演示:
python examples/v30_clinical_brief.py
# 可选:--model mlx,需要在 Apple 芯片设备上预先缓存固定版本的模型。该示例对内置记录进行去标识化、实体抽取和概念匹配,然后输出带来源引用的摘要、 核验结果和不含原始值的审核包。NER/NLI 提供程序是明确标注的合成测试替身, 不是经过训练的模型,也不代表临床验证。 不接受外部记录输入。 MLX 输出若缺乏证据支持会被拒绝,不会绕过保护检查。 详见摘要指南和演示脚本。
请从面向使用者的智能体指南开始,或加载精选的 llms.txt 文档索引。对于可调用的本地接口, 请使用 MCP 服务器、带类型的 工具注册表或 命令行接口。可直接使用的跨工具流程位于 仓库技能目录。
| 部署考量 | OpenMed SDK 边界 |
|---|---|
| 核心运行时 | 所需制品就绪后在本地处理 |
| 可选网络路径 | 下载、远程适配器、遥测路径和用户集成可能使用网络 |
| 验证 | 部署方验证模型与数据条款、隐私行为及临床适用性 |
| 接口 | 在受支持的范围内提供 Python、Swift、Android、浏览器和服务接口 |
- 精选模型目录:请针对你的用例验证每个模型、许可证和数据集。
- 与 Safe Harbor 对齐的配置:可面向 18 类标识符;仍需专家开展部署审查,使用 SDK 本身并不能证明符合 HIPAA。
- 受支持的执行路径:CPU、CUDA、MLX、移动端、服务和浏览器适配器会因环境与制品而异。
- 部署接口:Python、容器、服务和批处理工作流需要配置与验证。
- SDK 源代码:基于 Apache-2.0 License 发布;模型和数据集条款各不相同。
在受支持的 Apple 硬件上,所需制品就绪后,OpenMed 可使用 MLX 和 OpenMedKit 进行本地处理。模型获取和用户配置的远程集成仍是独立的网络边界。
// Add OpenMedKit to your app
dependencies: [
.package(url: "https://github.com/maziyarpanahi/openmed.git", from: "3.0.0"),
]预期结果:Swift Package Manager 解析 OpenMedKit,并让你的应用 target 可以使用
import OpenMedKit。
- MLX 运行时,用于 PII token 分类、Privacy Filter 系列、实验性的 GLiNER 系列 zero-shot 任务,以及通过 Laneformer 进行 Python MLX-LM 文本生成;对支持的 token 分类产物还提供 CoreML 回退路径。
- 一个模型名,所有平台:在非 Apple 硬件上,MLX 模型名会自动回退到对应的 PyTorch 检查点。
- Apple Silicon 上的 Python 同样支持:
pip install --upgrade "openmed[mlx]"。
指南:MLX 后端 · OpenMedKit (Swift) · CoreML 导出
OpenMedKit 也以原生 Android/Kotlin 库的形式提供,用于本地文档导入、OCR 交接、PII 脱敏,
并通过 ONNX Runtime Mobile 进行 token 分类推理。移动端模型仓库包含稳定的 tensor 名称、
动态序列轴、tokenizer 文件、标签,以及可供 Android 使用的 fp32、fp16、INT8 和可选 .ort 输出。
在 settings.gradle.kts 中添加限定范围的 JitPack 仓库:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven {
url = uri("https://jitpack.io")
content { includeGroup("com.github.maziyarpanahi") }
}
}
}然后使用不可变的 OpenMed v3.0.0 版本:
dependencies {
implementation("com.github.maziyarpanahi:openmed:v3.0.0")
}本地构建和发布详情参见 Android 安装指南。
val model = OpenMedKit.fromDirectory(modelDir)
val entities = model.analyzeText("Patient Alice Nguyen was seen in cardiology.")- Android ONNX 配置会生成
model.onnx、model_fp16.onnx、model_int8.onnx、tokenizer 资源、标签和openmed-onnx.json。 - ORT Mobile 支持会在安装 ONNX Runtime 转换工具时记录最小构建所需的算子配置。
- Kotlin 对等测试确保 tokenizer offset、span 边界和 decoder 输出与 Python 运行时保持一致。
指南:Android ONNX 导出 · Android span 对等性 · OpenMedKit Android
from openmed import OnnxModel
model = OnnxModel.from_pretrained(
"OpenMed/OpenMed-PII-ClinicalE5-Small-33M-v1-onnx-android"
)
entities = model("Patient Alice Nguyen was seen in cardiology.")npm install openmed @huggingface/transformersimport { loadOnnxModel } from "openmed";
const model = await loadOnnxModel(
"OpenMed/OpenMed-PII-ClinicalE5-Small-33M-v1-onnx-android",
);
const entities = await model("Patient Alice Nguyen was seen in cardiology.");flowchart LR
A["临床文本"] --> B["OpenMed<br/>(本地优先)"]
B --> C["医疗实体"]
B --> D["检测到的 PII"]
B --> E["去标识化文本"]
style B fill:#0D6E6E,stroke:#0A5656,stroke-width:2px,color:#ffffff
style C fill:#D6EBEB,stroke:#0D6E6E,color:#0E1116
style D fill:#F7DCD8,stroke:#C5453A,color:#0E1116
style E fill:#F5E27A,stroke:#A9A088,color:#0E1116
渲染结果:本地临床文本流水线会返回医疗实体、PII 检测结果和已去标识化文本, 无需将数据发送到云端 API。
skills/ 目录提供可移植的 Agent Skills,覆盖设备本地去标识化、临床 NER、FHIR 导出、评估以及相关医疗工作流。同一套 SKILL.md 文件夹可用于 Claude Code、OpenAI Codex、OpenCode 和兼容的智能体;安装脚本会使用各客户端的 skills 目录,并同时支持跨客户端约定 ~/.agents/skills。
git clone https://github.com/maziyarpanahi/openmed && cd openmed
./install-skills.sh # 安装到 Claude Code、Codex、OpenCode 和 ~/.agents/skills然后使用合成占位符让智能体生成流水线:
构建一个本地 OpenMed 流水线,对合成出院记录进行去标识化并抽取药物实体。
它会加载相应 skills,并生成设备本地流水线(openmed.deidentify(...) → openmed.analyze_text(...))。完成一次性模型下载后,请在本地使用该流水线处理真实病历;不要把真实 PHI 粘贴到云端智能体提示词中。参阅 skills 目录与 30 秒示例。
# 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]"预期结果:
Successfully installed openmed-...
|
Python API from openmed import analyze_text
result = analyze_text(
"Patient received 75mg "
"clopidogrel for NSTEMI.",
model_name=
"pharma_detection_superclinical",
)
print([(e.label, e.text) for e in result.entities])示例输出: |
REST 服务 python -m openmed.service.logging \
--host 0.0.0.0 --port 8080示例输出:
|
批处理 from openmed import BatchProcessor
p = BatchProcessor(
model_name=
"disease_detection_superclinical",
group_entities=True,
)
results = p.process_texts([...])
print(len(results), sum(len(r.entities) for r in results))
print([(e.label, e.text) for e in results[0].entities[:1]])示例输出: |
浏览器 / WebGPU
通过 Transformers.js 打包 ONNX token 分类导出,以便在浏览器中进行推理:
python -m openmed.onnx.convert \
--model dslim/bert-base-NER \
--output dist/example-onnx \
--include-transformersjs示例输出:
Exported Transformers.js bundle to dist/example-onnx
import { pipeline } from "@huggingface/transformers";
const detector = await pipeline(
"token-classification",
"/models/openmed-pii/transformersjs",
{ device: "webgpu" },
);
const entities = await detector("Patient Casey Example called 212-555-0198.");
console.log(entities.slice(0, 2));示例输出:
[
{ entity: "NAME", word: "Casey Example", score: 0.99 },
{ entity: "PHONE", word: "212-555-0198", score: 0.98 },
]离线 / 隔离网络? 只需将 model_name(或 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"),
)
for entity in result.entities:
print(f"{entity.label:<12} {entity.text:<28} {entity.confidence:.2f}")示例输出:
DISEASE chronic myeloid leukemia 0.98
DISEASE Type 2 diabetes 0.96
由于 model_id 指向本地目录,本示例不会连接 Hugging Face Hub 或任何外部模型提供方。
精选的专业医疗 NER 模型注册表,浏览完整目录。
| 模型 | 专长 | 实体类型 | 大小 |
|---|---|---|---|
disease_detection_superclinical |
疾病与病症 | DISEASE, CONDITION, DIAGNOSIS | 434M |
pharma_detection_superclinical |
药物与用药 | DRUG, MEDICATION, TREATMENT | 434M |
pii_superclinical_large |
PII 与去标识化 | NAME, DATE, SSN, PHONE, EMAIL, ADDRESS | 434M |
anatomy_detection_electramed |
解剖与身体部位 | ANATOMY, ORGAN, BODY_PART | 109M |
gene_detection_genecorpus |
基因与蛋白质 | GENE, PROTEIN | 109M |
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)
print([(e.label, e.text) for e in result.entities])
# De-identify with the method you need
print(deidentify(text, method="mask").deidentified_text)
print(deidentify(text, method="replace").deidentified_text)
print(deidentify(text, method="hash").deidentified_text)
print(deidentify(text, method="shift_dates", date_shift_days=180).deidentified_text)示例输出:
[('NAME', 'John Doe'), ('DATE', '01/15/1970'), ('SSN', '123-45-6789')]
Patient: [NAME], DOB: [DATE], SSN: [SSN]
Patient: Emily Chen, DOB: 03/22/1985, SSN: 456-78-9012
Patient: 6b8f...c4a1, DOB: 48b1...91de, SSN: 3f13...e912
Patient: John Doe, DOB: 07/14/1970, SSN: 123-45-6789
- 智能实体合并让
01/15/1970保持完整,而不会被拆分。 - 策略感知流水线提供 HIPAA/GDPR/研究配置、校准阈值、签名审计报告、脱敏预览,以及最小必要操作选择。
- 基于 Faker 的混淆,内置自定义临床证件号 provider(CPF、CNPJ、BSN、NIR、Codice Fiscale、NIE、Aadhaar、Steuer-ID、NPI)。
- HIPAA 边界:与 Safe Harbor 对齐的类别和可配置阈值属于实现辅助;仍需专家开展部署审查,仅使用 SDK 并不能证明合规。
- 批量与流式 PII 处理:使用
BatchProcessor(operation="extract_pii" | "deidentify", batch_size=16)或增量流式辅助函数,对大量文档进行抽取或去标识化。
完整 PII 笔记本 · 智能合并 · 匿名化快速入门
Privacy Filter 系列:基于 OpenAI Privacy Filter 架构的三个模型系列
模型代码相同(gpt-oss 风格的稀疏 MoE Transformer,带局部注意力、sink token、RoPE+YaRN、tiktoken o200k_base 分词),仅训练数据不同。它们都通过同一套 extract_pii() / deidentify() API 调用,只需更改 model_name= 参数。
openai/privacy-filter 是本地权重在 Hugging Face 上的模型标识符;
在此使用它不会调用 OpenAI API。
| 变体 | PyTorch (CPU + CUDA) | MLX (Apple Silicon) | MLX 8-bit |
|---|---|---|---|
| OpenAI Privacy Filter | openai/privacy-filter |
OpenMed/privacy-filter-mlx |
…-mlx-8bit |
| Nemotron-PII fine-tune | OpenMed/privacy-filter-nemotron |
…-nemotron-mlx |
…-nemotron-mlx-8bit |
| OpenMed Multilingual | OpenMed/privacy-filter-multilingual |
…-multilingual-mlx |
…-multilingual-mlx-8bit |
from openmed import extract_pii
text = "Patient Sarah Connor (DOB: 03/15/1985) at MRN 4471882."
variants = {
"baseline": extract_pii(text, model_name="openai/privacy-filter"),
"nemotron": extract_pii(text, model_name="OpenMed/privacy-filter-nemotron"),
"mlx": extract_pii(text, model_name="OpenMed/privacy-filter-mlx"),
}
print([(e.label, e.text) for e in variants["baseline"].entities])示例输出:
[('NAME', 'Sarah Connor'), ('DATE', '03/15/1985'), ('ID', '4471882')]
在非 Apple Silicon 主机上,MLX 模型名会自动替换为对应的 PyTorch 检查点(并给出一次性警告),写一个模型名,随处运行。参见 Privacy Filter 架构与后端路由。
实体抽取和去标识化支持 40 个 PII 语言代码:
am、ar、as、bn、cs、da、de、el、en、es、fa、fr、gu、he、hi、id、it、ja、kn、ko、ml、mr、nl、no、or、pa、pt、ro、ru、sv、sw、ta、te、th、tr、uk、vi、xh、zh 和 zu,共计 已登记的 PII 模型目录。
俄语路由目前使用文档中说明的多语言默认模型占位符。孟加拉语、中文和泰米尔语拥有专用注册表条目。
一个由用户选择并配置的印度语言 NER 系列可服务于阿萨姆语、孟加拉语、古吉拉特语、印地语、卡纳达语、马拉雅拉姆语、马拉地语、奥里亚语、旁遮普语、泰米尔语和泰卢固语。请设置 OPENMED_INDIC_NER_MODEL;
OpenMed 不会捆绑或自动选择这些权重。
OpenMed 还为其他仅含证件号的语言区域提供基于 validator 的国家证件号覆盖,
例如拉脱维亚、斯洛伐克、马来西亚、菲律宾和芬兰。
各语言代码的默认 PII 模型、Faker locale 和去标识化前后示例,参见分语言指南。
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])"示例输出:
[('NAME', 'Pedro Almeida'), ('ID', '123.456.789-09'), ('EMAIL', 'pedro@hospital.pt')]
查看各语言示例(葡萄牙语、荷兰语、印地语、阿拉伯语、日语、土耳其语)
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])示例输出:
[('NAME', 'Pedro Almeida'), ('ID', '123.456.789-09'), ('PHONE', '+351 912 345 678')]
[('NAME', 'Eva de Vries'), ('ID', '123456782'), ('PHONE', '+31 6 12345678')]
[('NAME', 'अनीता शर्मा'), ('PHONE', '+91 9876543210'), ('ADDRESS', 'नई दिल्ली 110001')]
[('NAME', 'ليلى حسن'), ('PHONE', '+20 10 1234 5678'), ('ID', '29801011234567')]
[('NAME', '佐藤 花子'), ('PHONE', '+81 90 1234 5678'), ('ID', '1234 5678 9012')]
[('NAME', 'Ayşe Yılmaz'), ('PHONE', '+90 532 123 45 67'), ('ID', '10000000146')]
一个对 Docker 友好的 FastAPI 服务,具备请求校验、共享流水线预加载,以及统一的错误响应封装。
pip install --upgrade "openmed[hf,service]"
python -m openmed.service.logging --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示例输出:
INFO: Uvicorn running on http://0.0.0.0:8080
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"}'简化的响应示例:
{
"text": "Paciente: Maria Garcia, DNI: 12345678Z",
"entities": [
{"text": "Maria Garcia", "label": "NAME", "confidence": 0.99, "start": 10, "end": 22},
{"text": "12345678Z", "label": "ID", "confidence": 0.98, "start": 29, "end": 38}
],
"model_name": "OpenMed/privacy-filter-multilingual"
}**模型生命周期和服务控制:**通过 GET /models/loaded、POST /models/unload
和 keep_alive 空闲时限按需释放内存;v1.8 还提供 API key/JWT 身份验证、
不含 PHI 的请求日志、tracing、gRPC、异步任务、webhook、warm pool、动态批处理、
请求合并、速率与并发限制、/livez、/readyz 和可选 metrics:
OPENMED_SERVICE_KEEP_ALIVE=10m python -m openmed.service.logging --host 0.0.0.0 --port 8080
curl -X POST http://127.0.0.1:8080/models/unload -H "Content-Type: application/json" -d '{"all":true}'示例响应:
{
"unloaded": true,
"released": {"models": 1, "tokenizers": 1, "pipelines": 1},
"active_models": {}
}参见完整的 REST 服务指南。
完整指南见 openmed.life/docs。
AI 智能体可以加载精选的 llms.txt 索引,或加载内联全文的 llms-full.txt 信息流。每次严格构建 MkDocs 时,两者都会根据当前文档重新生成。
| 快速入门 | 文本分析 | 模型注册表 |
| 常见问题 | 匿名化 | 批处理 |
| 配置档案 | REST 服务 | MLX 后端 |
| Transformers.js 导出 | FHIR 互操作 | HL7 v2 去标识化 |
| OpenMed 3.0.0 迁移指南 | OpenMed 2.2.0 发行说明 | 示例 |
| 发布通道 | 生成式模型策略 | 贡献指南 |
| 安全策略 | 合规状态 | 扩展插件 SDK |
| v1 到 v2 迁移 | MCP 客户端连接 | 非洲开发者入门 |
OpenMed 的守护者是一只蓬松的波斯猫,化身为小小的阿维森纳(伊本·西那,Avicenna / Ibn Sina),这位伟大的 波斯医师所著的《医典》(Canon of Medicine)在约 600 年间一直是全世界的标准医学教科书。它守护着翻开的 医学知识之书,配色取自波斯绿松石(fīrūza):一位守护你最私密数据的本地优先卫士。
欢迎贡献:bug 报告、功能请求和 PR 都欢迎。请先阅读贡献指南和行为准则。
发现漏洞?OpenMed 会对 PHI 进行脱敏,因此脱敏绕过或 PHI/PII 泄漏属于安全问题: 请通过私密渠道报告,切勿提交公开 issue。负责任披露政策参见 SECURITY.md, 也可使用私密报告表单。 报告中绝不能包含真实患者数据。
OpenMed 建立在优秀的开源工作之上:特别感谢 OpenAI(Privacy Filter 架构)、NVIDIA(Nemotron PII 数据集)、Hugging Face(transformers、Transformers.js 及模型生态)、Apple(MLX),以及 Faker 的维护者。
OpenMed SDK 源代码基于 Apache-2.0 License 发布。第三方资源声明记录在 NOTICE 中。
@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},
url={https://arxiv.org/abs/2508.01630},
}预期结果:可在论文、海报和衍生文档中引用 OpenMed 的 BibTeX 兼容元数据。
如果 OpenMed 对你有帮助,点个 star 能帮助更多人发现它。
5,400+ GitHub stars · 9 Oct 2026 snapshot
由 OpenMed 团队打造
网站 · 文档 · X / Twitter · LinkedIn



