读书有三到:谓心到,眼到,口到。——明朱熹

https://github.com/maziyarpanahi/openmed

OpenMed:把医疗 AI 请回本地,让数据安心留在身边

医疗文本每天都在说话。

病历在说话,出院小结在说话,检验记录在说话,药物信息在说话,患者隐私也在说话。只是过去很多时候,我们想听懂它们,往往要把这些信息交给云端,交给外部服务,交给一层又一层看不见的系统去拆解、去判断、去返回结果。

而 OpenMed 像一位不喜欢张扬、却极其可靠的临床助手,轻轻把门关上,说了一句:这些事,不必出门,我可以在本地做完。

它的仓库描述只有一句话:open-source healthcare ai。

可真打开 README,你会发现这不是一句轻飘飘的口号。OpenMed 的气质非常鲜明:它是一个本地优先的医疗 AI 工具,把临床文本分析、医疗实体抽取、PII 检测与去标识化、批处理、REST 服务,甚至原生 iPhone 与 Mac 端的运行能力,全都拉回到你自己的设备和基础设施上。它不热衷于把数据送上云,它更像一位守门人,安静地站在你的机器旁边,替你把住隐私与效率这道关。


它最打动人的地方,是那句近乎倔强的承诺

OpenMed 在 README 里反复强调一件事:clinical text never leaves the device

这不是装饰性的宣传语,而是整个项目的性格底色。

在很多医疗场景里,最珍贵的并不是模型本身,而是数据的边界感。患者姓名、出生日期、病历号、联系方式、地址、账单信息,这些内容一旦离开受控环境,就意味着风险开始长脚。OpenMed 明白这一点,所以它选择了一条很硬核、也很难走的路:100% on-device

它不要求你先申请 API Key,不催你先配置云服务,不暗示你先把数据发给第三方平台。它更像一位把白大褂穿得整整齐齐的工程师,对你说:

我就在这里。
把文本给我。
别担心,我不会让它离开你的网络。

这种克制,在当下其实很迷人。


OpenMed 到底能做什么

如果把 OpenMed 拟人化,它像是一位兼具临床理解能力、隐私意识和工程素养的多面手。

它能读懂医疗文本,从中识别出疾病、药物、解剖结构、基因蛋白等关键信息;它也能像一位认真谨慎的隐私专员,把姓名、日期、身份证号、电话、邮箱、住址等敏感信息一一揪出来,再按你的要求完成去标识化;它还懂得如何在 Python 脚本里低调干活,如何变成一个 Docker 友好的 REST 服务,甚至知道怎样在 iPhone、iPad、macOS 上以原生方式安静运行。

README 里最亮眼的几组关键词,几乎可以直接勾勒出它的轮廓:

  • 1,000+ specialized medical models
  • 12 languages
  • 247 PII checkpoints
  • 100% on-device
  • Apache-2.0

这些数字放在一起,很像它递过来的一张名片:我不只是能用,我还很全面;我不只是本地运行,我还覆盖了真实世界里复杂的医疗语料与隐私处理需求。


它像一个懂医疗的拆解师,把杂乱临床文本变成结构化洞见

OpenMed 最核心的能力之一,是把自然语言形式的临床文本,转成结构化的医学信号。

想象一段病历描述:

患者开始接受 imatinib 治疗,用于 chronic myeloid leukemia。

在很多系统里,这只是一行字符串;在 OpenMed 眼里,这是一段等待被拆开的临床语义。它会把疾病识别出来,把药物识别出来,把置信度给出来,像一位训练有素的标注专家,迅速把混杂在句子里的关键信息一一拎出。

README 中给出的示例非常直观:

1
2
3
4
5
6
7
8
9
10
11
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 的迷人之处。它不像一些工具那样,总要先搭好一套庞大的工程舞台才肯开口。它更像一个经验老到的医生助理,你刚递给它病历,它已经开始圈重点了。


它不是泛泛而谈的医疗 AI,而是带着“专科意识”来的

OpenMed 并不满足于做一个模糊的“文本理解工具”。它更像一个知道分科、知道边界、知道任务差异的医疗 AI 平台。

在 README 的模型表中,它列出了不同专长方向的模型,例如:

  • disease_detection_superclinical 负责疾病与诊断相关实体
  • pharma_detection_superclinical 负责药物与治疗相关实体
  • pii_superclinical_large 负责隐私信息与去标识化
  • anatomy_detection_electramed 负责解剖结构
  • gene_detection_genecorpus 负责基因与蛋白

这意味着 OpenMed 并不是把所有任务硬塞给一个笼统模型处理,而更像一个医院里的协同团队。你要找疾病,它请擅长疾病识别的模型上场;你要找药物,它换药学更敏锐的模型;你要处理 PII,它立刻把隐私专家叫来。

这种专门化设计,让它显得很“临床”,也很“工程”。

它不像一个只会喊口号的全能型选手,倒像一支训练有素的科室团队:谁擅长什么,谁处理什么,分工明确,落地踏实。


真正让它有灵魂的,是隐私处理能力

如果说医疗实体抽取让 OpenMed 看起来聪明,那么 PII 检测与去标识化能力,则让它看起来可靠。

在医疗 AI 场景里,可靠往往比聪明更重要。

你可以接受一个模型偶尔对边缘实体判断不准,但你很难接受它把患者姓名、电话号码、证件号、出生日期、地址这些敏感信息暴露出去。OpenMed 显然很清楚这一点,所以它把隐私保护这件事,做得既认真又具体。

README 中的示例代码非常实用:

1
2
3
4
5
6
7
8
9
10
11
12
from openmed import extract_pii, deidentify

text = "Patient: John Doe, DOB: 01/15/1970, SSN: 123-45-6789"

# Extract PII with smart merging
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)

这段代码给人的感觉非常像一个经验充足的档案管理员。

它先把敏感信息识别出来,再根据你的需求选择处理方式:

  • 可以直接遮罩
  • 可以替换成格式保持一致的虚构数据
  • 可以做加密哈希
  • 可以做日期偏移

这不是单一的“打码”思路,而是一整套更成熟的隐私治理工具箱。你面对不同业务场景、不同合规要求、不同研究需求时,都有相对合适的处理方式可选。

更重要的是,OpenMed 还强调了几个很关键的细节:

  • 支持 smart entity merging
  • 覆盖 HIPAA Safe Harbor 的 18 类标识符
  • 可配置置信度阈值
  • 支持批量 PII 提取与去标识化

所谓 smart entity merging,很像它对文本碎片的一种温柔修补。比如日期 01/15/1970,有些系统会把它切得七零八落,而 OpenMed 尽量把它作为一个完整实体保留下来。这种细节处理非常能说明问题:它不是只想“识别一些 token”,它是想在真实文档里,把隐私信息尽可能完整、准确、可用地识别出来。

这种认真,会让人产生信任。


多语言支持,让它不像只会英语的专家,而像真正走进世界各地医院的人

OpenMed 支持 12 种语言的 PII 提取与去标识化,包括:

  • en
  • fr
  • de
  • it
  • es
  • nl
  • hi
  • te
  • pt
  • ar
  • ja
  • tr

而且 README 明确提到共有 247 PII checkpoints

这件事的重要性常常被低估。现实里的医疗数据从来不是单一语言的整齐世界,尤其当系统面对跨地区机构、国际研究、移民医疗服务、多语种病患资料时,多语言支持不是加分项,而是实际生产力的一部分。

OpenMed 在这方面不像只会在英文世界发言的学者,倒像一个愿意换不同语言和患者打招呼的临床同伴。面对葡萄牙语、荷兰语、印地语、阿拉伯语、日语、土耳其语,它都尽量保持识别与去标识化能力的一致性。

README 甚至给了一个非常直白的命令行示例:

1
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])"

这个示例很短,却很有力量。它告诉你,多语言处理并不是 PPT 上的承诺,而是可以直接跑起来的日常能力。


它还有一种特别难得的品质:不是只会在服务器里工作,它还会去手机上帮你

很多项目一谈到本地 AI,默认语境还是 Linux 服务器、GPU 机器、Python 环境。OpenMed 则更进一步,它不仅考虑桌面和服务端,还在认真经营 Apple 生态。

README 里对 Apple 硬件的支持写得非常明确:

  • 支持 Apple Silicon
  • 使用 MLX 加速
  • 可通过 OpenMedKit 进入 iPhone、iPad、macOS 原生应用
  • 支持完全离线的本地处理

这让 OpenMed 像一个不愿只待在机房里的工具。它愿意走到医生手边,走进移动端场景,走进真正需要随时使用、随地使用的终端环境。

Swift 依赖示例也很直接:

1
2
3
dependencies: [
.package(url: "https://github.com/maziyarpanahi/openmed.git", from: "1.5.5"),
]

这意味着它不只会在 Python 世界里埋头苦干,它还会穿上一身 Swift 的外套,进入 iOS 和 macOS 应用里继续工作。对于医疗软件、临床辅助工具、移动端脱敏扫描场景来说,这种能力非常有吸引力。

更有意思的是,README 提到在 Apple Silicon 上,MLX 对 Privacy Filter 的推理速度可达到相对 CPU PyTorch 明显更高的表现。它像是终于找到了最懂自己的硬件搭档,配合起来格外默契。


Quick Start 这部分非常友好,像它主动给你递来第一把钥匙

一个项目值不值得试,很多时候就看它愿不愿意让你轻松迈出第一步。

OpenMed 的 Quick Start 写得很清楚,门槛也压得很低。

安装方式

1
2
3
4
5
6
7
8
# Core + Hugging Face runtime
pip install "openmed[hf]"

# Add the REST service
pip install "openmed[hf,service]"

# Apple Silicon acceleration
pip install "openmed[mlx]"

这几行命令很像它在门口等你,然后按你的使用场景给出不同入口:

  • 你只是想在 Python 里跑起来,用 openmed[hf]
  • 你想顺手变成服务,用 openmed[hf,service]
  • 你在 Apple Silicon 上追求本地加速,用 openmed[mlx]

这种设计没有把用户逼进唯一答案里,而是给了几条自然的路径。

Python API 示例

1
2
3
4
5
6
7
8
from openmed import analyze_text

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

这段代码很适合刚接触的人。它没有复杂封装,没有堆满概念,只是安安静静地告诉你:我会分析这段医疗文本。

批处理示例

1
2
3
4
5
6
7
8
from openmed import BatchProcessor

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

当你的场景从单条文本转向多文档处理时,OpenMed 也没有慌。它像一个从门诊走到住院部依然游刃有余的人,直接给出批处理能力。

离线与隔离网络场景

这一点尤其值得一提。README 里明确说,如果你处于 offline 或 air-gapped 场景,可以把 model_namemodel_id 指向本地目录,OpenMed 会直接加载本地模型,而不会联系 Hugging Face Hub。

1
2
3
4
5
6
7
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"),
)

这像极了它对高安全环境的一种郑重理解。它知道有些数据中心、有些医疗机构、有些研究环境,天生就不欢迎联网依赖,所以它干脆学会了在完全本地的条件下独立完成工作。

不是“尽量适配”,而是“我本来就是为这种场景准备的”。


它不仅能做库,还愿意做服务

很多开源项目停留在“库很好用”,但真正走向团队协作、系统集成时,大家更需要的是服务能力。OpenMed 没有回避这一层,而是提供了 Docker 友好的 FastAPI 服务方案。

README 中的启动方式非常直接:

1
2
pip install "openmed[hf,service]"
uvicorn openmed.service.app:app --host 0.0.0.0 --port 8080

它暴露的接口也很清晰:

1
2
3
4
GET /health
POST /analyze
POST /pii/extract
POST /pii/deidentify

如果你更喜欢容器化,也可以这样跑:

1
2
docker build -t openmed:1.5.5 .
docker run --rm -p 8080:8080 -e OPENMED_PROFILE=prod openmed:1.5.5

然后直接发请求:

1
2
3
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 的定位并不狭窄。它不是一个只能在 notebook 里展示的研究玩具,也不是只适合单机实验的模型包装器。它显然想走进实际系统,走进服务架构,走进团队开发流程。

它像一个既能独立值班、也能融入医院大系统的成员。


为什么很多人会对 OpenMed 有好感

因为它的价值表达非常坦率。

README 中有一个对比表,把 OpenMed 和传统云医疗 API 的差异讲得很直白:

  • 数据是否留在设备或服务器上
  • 患者数据是否离开网络
  • 成本模式
  • 专业模型数量
  • 语言支持
  • 是否支持离线或隔离网络
  • 是否支持 Apple Silicon 加速
  • 是否能进入原生 iOS/macOS 应用
  • 是否存在厂商锁定

这种对比其实传达了一个更深层的态度:OpenMed 不只是提供能力,它还在试图改变默认选择。

过去很多团队默认认为,要获得医疗 AI 能力,就得接受外部 API、按调用付费、数据外发、能力边界受制于供应商。OpenMed 则像一个坚定的反问者:

为什么不能自己掌握模型?
为什么不能让数据待在本地?
为什么不能离线运行?
为什么不能既开放又专业?

所以它的吸引力,不只是来自“功能多”,更来自“立场清楚”。


它甚至连形象都设计得很有温度

OpenMed 的 README 里还有一处很可爱,也很有记忆点:它有自己的 mascot。

一只 fluffy Persian cat,被塑造成小小的 Avicenna,也就是 Ibn Sina 的形象,守护着一本打开的医学知识之书。配色围绕 Persian turquoise 展开,象征一种本地优先、守护隐私的气质。

这段设定很妙。

因为 OpenMed 整个项目本来就有一种“守护者”的角色感:它站在医疗文本与外部世界之间,替你看住最私密的数据;它站在工程与临床之间,把难以处理的文本变成结构化结果;它站在开放与实用之间,尽量不给使用者增加锁定与依赖。

所以那只波斯猫并不只是一个品牌装饰,它更像 OpenMed 的人格投影。

看上去柔软,实际上很警觉。
看上去温和,实际上很能守。
它不吵闹,但它把重要的东西看得很牢。


如果你是开发者,OpenMed 很适合这些场景

读完整个 README 后,我会觉得 OpenMed 特别适合以下几类人和团队:

1. 需要处理医疗文本,但不希望把数据送上云的团队

如果你的系统里涉及患者文本、病历摘要、检查记录、临床描述,且对隐私边界非常敏感,那么 OpenMed 的本地优先思路会非常有吸引力。

2. 想做医疗实体抽取、药物识别、疾病检测的开发者

它的模型体系明确、示例清楚,而且使用方式足够轻量,很适合快速验证任务。

3. 需要做 PII 识别与去标识化的产品或研究团队

尤其当你不仅想“打码”,还想要更灵活的脱敏策略时,OpenMed 提供的多种方法会很实用。

4. Apple 生态开发者

如果你正考虑把本地医疗 AI 能力带到 iPhone、iPad、Mac 上,OpenMedKit 与 MLX 路线会格外值得关注。

5. 需要 REST 服务、批量处理、离线部署能力的工程团队

从库到服务,从单条处理到批处理,从联网环境到 air-gapped 场景,OpenMed 都留出了通路。


我很喜欢它“只做该做的事”的气质

有些开源项目会试图把自己包装成万能宇宙平台,什么都想做,什么都想占。OpenMed 给我的感觉不是这样。

它的方向非常集中:医疗文本理解 + 隐私保护 + 本地运行 + 开放生态

这种聚焦让它显得更可信。它像一位很清楚自己职责边界的临床助手,不抢戏,不夸口,但在自己负责的那几件事上尽可能做到扎实、完整、可落地。

而且它的叙事里有一种非常鲜明的工程诚意:

  • 给你 Python 一行代码入口
  • 给你批处理能力
  • 给你 REST API
  • 给你 Docker 方案
  • 给你离线加载方式
  • 给你 Apple 设备侧落地路径
  • 给你多语言 PII 处理
  • 给你 Apache-2.0 许可

它并不是只会告诉你“我很先进”,而是在不断告诉你“你可以怎么真正用我”。


最后聊聊它为什么值得被更多人看见

OpenMed 的仓库名称不喧哗,description 也克制得像一句简单自我介绍:open-source healthcare ai。

但它真正吸引人的地方,恰恰就在这份克制之后。

它不靠神秘感取胜,也不靠云端权威感取胜。它更像一个把能力摊开放在桌面上的人:你可以检查它、部署它、嵌入它、扩展它、在自己的机器上运行它,让它在真正需要守护隐私的地方工作。

在今天这个人人都在谈 AI 的时代,OpenMed 提醒了我们一件特别重要的事:

不是所有智能,都必须以交出数据为代价。
不是所有效率,都必须建立在外部依赖之上。
不是所有医疗 AI,都注定离临床现场很远。

OpenMed 像一位谨慎、可靠、懂分寸的本地医生助理,把医疗文本接过来,把隐私护住,把结构化结果交还给你,然后安静地站回设备旁边。

它不需要把门打开,
也能把事情做好。

如果你正在寻找一个真正尊重数据边界、同时又足够实用的开源医疗 AI 项目,那么 OpenMed 很值得你认真看看。它不是那种只适合远观的项目,它更像一个可以被真正请进系统里、长期并肩工作的伙伴。

而在这个意义上,OpenMed 也许不只是一个工具。

它更像医疗 AI 世界里,一个终于愿意把患者隐私轻轻抱回本地的人。