База знаний
OpenMed — локальные медицинские ИИ-модели для клинического NER и обезличивания
OpenMed — открытый набор медицинских ИИ-моделей для клинического NER и обезличивания данных. Работают локально на устройстве или сервере, без облака.
СейчасЧто такое OpenMed
- Что такое OpenMed
- Что умеет: основные возможности
- Как это работает
- Подключение и интеграция
- Python
- REST-сервис (Docker)
- Apple Silicon и iOS
- Браузер
- Модели: с чего начать
- Приватность: обезличивание и PII
- Тарифы и лимиты
- Применение в России: нюансы, проблемы и как подступиться
- Что говорит закон
- Главная техническая проблема: русский язык
- ПО как медицинское изделие
- Интеграция с российским ИТ-контуром
- Как всё-таки применить
- Дообучение под русский корпус: пошаговая инструкция
- Полезные ссылки
OpenMed — открытый набор медицинских ИИ-моделей для распознавания клинических сущностей и обезличивания персональных данных. Работают локально: на ноутбуке, телефоне или вашем сервере, и данные пациента никуда не уходят.
Что такое OpenMed
OpenMed — семейство специализированных моделей для обработки медицинского текста. Групп две: клинический NER (извлечение сущностей вроде болезней, препаратов, генов, анатомии) и обезличивание персональных данных (PII). Проект открыт по лицензии Apache-2.0, модели небольшие и рассчитаны на локальный запуск. Автор — Maziyar Panahi (CNRS, Париж), к проекту приложена научная статья с замерами на 12 биомедицинских датасетах.
По цифрам проекта: свыше 1500 моделей на Hugging Face, 15 языков для обезличивания, 247 PII-чекпойнтов, десятки миллионов загрузок. Всё бесплатно и с открытыми весами.
Что умеет: основные возможности
| Возможность | Что делает |
| Клинический NER | Извлекает болезни, препараты, гены, белки, анатомию, химические вещества и онкологические сущности из текста |
| Обезличивание | Находит и маскирует персональные данные по всем 18 идентификаторам HIPAA Safe Harbor |
| Локальный запуск | CPU, CUDA, Apple Silicon (MLX), iPhone/iPad/Mac через OpenMedKit, браузер через Transformers.js/WebGPU |
| Форматы и интеграция | Клинический текст на входе; для медицинских систем есть интеграция с HL7 v2 и FHIR |
| Языки обезличивания | 15 языков (см. раздел про приватность). Русского в списке нет |
Как это работает
Одна функция принимает текст и возвращает размеченные сущности. По сети при этом ничего не отправляется.
flowchart LR
A["Клинический текст"] --> B["OpenMed (100% локально)"]
B --> C["Медицинские сущности"]
B --> D["Найденные PII"]
B --> E["Обезличенный текст"]Подключение и интеграция
Python
Базовая установка и первый вызов:
# Ядро + рантайм Hugging Face (Linux, macOS, Windows; CPU или CUDA)
pip install "openmed[hf]"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(entity.label, entity.text, entity.confidence)
# DISEASE chronic myeloid leukemia 0.98
# DRUG imatinib 0.95REST-сервис (Docker)
Для интеграции с бэкендом поднимается FastAPI-сервис:
pip install "openmed[hf,service]"
uvicorn openmed.service.app:app --host 0.0.0.0 --port 8080
# либо через Docker
docker run --rm -p 8080:8080 -e OPENMED_PROFILE=prod openmed:1.7.0Эндпоинты: GET /health, POST /analyze, POST /pii/extract, POST /pii/deidentify.
Apple Silicon и iOS
На Mac и iPhone инструмент работает через Swift-пакет OpenMedKit с ускорением MLX. По замерам проекта MLX на Apple Silicon даёт до 24–33× ускорения относительно CPU. Установка Python-варианта с MLX:
pip install "openmed[mlx]"Браузер
Токен-классификацию можно упаковать в ONNX и запускать прямо в браузере через Transformers.js на WebGPU, без сервера.
Модели: с чего начать
| Модель | Специализация | Сущности | Размер |
| disease_detection_superclinical | Болезни и состояния | DISEASE, CONDITION, DIAGNOSIS | 434M |
| pharma_detection_superclinical | Препараты | DRUG, MEDICATION, TREATMENT | 434M |
| pii_superclinical_large | Обезличивание | NAME, DATE, SSN, PHONE, EMAIL, ADDRESS | 434M |
| anatomy_detection_electramed | Анатомия | ANATOMY, ORGAN, BODY_PART | 109M |
| gene_detection_genecorpus | Гены и белки | GENE, PROTEIN | 109M |
Полный каталог — на сайте проекта в разделе Model Registry.
Приватность: обезличивание и PII
PII-модели находят все 18 идентификаторов HIPAA Safe Harbor и маскируют их. Есть «умное склеивание» токенов (чтобы дата 01/15/1970 не разбивалась на куски), политики HIPAA/GDPR, подписанные отчёты аудита и предпросмотр редактуры.
Поддерживаемые языки обезличивания: ar, de, en, es, fr, he, hi, id, it, ja, nl, pt, te, th, tr.
ru) в списке нет. Для русского клинического текста готовые PII-модели OpenMed из коробки не работают. Подробнее — в разделе про Россию.Тарифы и лимиты
Основное бесплатно и открыто. Веса, код и рецепты обучения под Apache-2.0, можно использовать в исследованиях и в продакшене без оплаты. Для тех, кому нужен управляемый вариант, часть моделей доступна как пакеты на AWS Marketplace и SageMaker с HIPAA-совместимыми эндпоинтами. Это уже платный облачный путь, и для российского контура он, как правило, не подходит (см. ниже).
Применение в России: нюансы, проблемы и как подступиться
Это самый важный раздел, если вы работаете с данными российских пациентов. Здесь три слоя: закон, язык и интеграция.
Что говорит закон
- 152-ФЗ «О персональных данных». Данные о здоровье — специальная категория (ст. 10). К их обработке предъявляются повышенные требования: отдельное согласие, усиленная защита.
- Локализация (ст. 18, ч. 5). Запись, систематизация и хранение персональных данных россиян должны идти в базах на территории РФ. Локальный и on-prem-запуск OpenMed сюда вписывается: данные физически не покидают ваш сервер.
- Врачебная тайна (ст. 13 ФЗ-323 «Об основах охраны здоровья граждан»). Передача сведений о пациенте третьим лицам ограничена. On-device-подход снимает риск утечки во внешний сервис.
- Обезличивание. Требования к обезличиванию задаёт Роскомнадзор. Нюанс: обезличивание OpenMed калибровалось под HIPAA, а не под российские правила, поэтому набор полей и логику нужно проверять и настраивать под 152-ФЗ.
Здесь и кроется сильная сторона инструмента для РФ: локальная обработка закрывает сразу и локализацию, и врачебную тайну.
Главная техническая проблема: русский язык
Модели обучены на англоязычных биомедицинских корпусах (PubMed, arXiv, MIMIC-III) и на англоязычных датасетах NER (BC5CDR, NCBI-Disease и других). Русского в списке языков PII нет вовсе.
Что это значит на практике:
- Готовые модели хорошо разбирают английский клинический текст и научную литературу.
- На русской карте пациента они работать не будут: другой алфавит, другая терминология, другие форматы документов и идентификаторов (СНИЛС, полис ОМС, паспорт вместо SSN).
- Российские справочники (МНН, ЖНВЛП, коды МКБ на русском) в модель не заложены.
ПО как медицинское изделие
Если инструмент влияет на постановку диагноза или выбор лечения, он может подпадать под регулирование программного обеспечения как медицинского изделия и требовать регистрации в Росздравнадзоре. Извлечение сущностей для исследований и внутренней аналитики обычно в эту категорию не попадает, но границу стоит оценивать под конкретный сценарий.
Интеграция с российским ИТ-контуром
- Российские МИС и ЕГИСЗ не всегда говорят на FHIR/HL7, хотя движение в эту сторону идёт. Поддержка FHIR/HL7 в OpenMed поможет там, где стандарты уже внедрены.
- Apple-стек (MLX, OpenMedKit) удобен, но не обязателен: сервис поднимается на обычном Linux-сервере с CPU или GPU, что проще для российской инфраструктуры.
Как всё-таки применить
- Обработка англоязычной литературы и исследований. Майнинг статей, извлечение препаратов и болезней из зарубежных источников работает из коробки.
- Обезличивание перед отправкой в облачную LLM. Схема «сначала локально обезличить, потом отправить» ценна сама по себе. Для русского текста PII-часть придётся заменить или дообучить.
- Дообучение под русский язык. Подход из статьи (лёгкий domain-adaptive pretraining плюс LoRA) описан и воспроизводим. На открытых весах модель можно дообучить на русском клиническом корпусе. Задача реальная, хотя и небыстрая, для ML-команды. Пошаговый рецепт — в отдельном разделе ниже.
- Связка с российскими решениями. Для русского текста разумно комбинировать OpenMed с локальными русскоязычными моделями и инфраструктурой (например, on-prem-платформами вроде NeuralDeep), оставляя за OpenMed англоязычную часть и саму архитектуру обезличивания.
- On-prem-пилот в клинике. Развернуть сервис в закрытом контуре, прогнать на обезличенных данных, оценить качество и только потом расширять.
Дообучение под русский корпус: пошаговая инструкция
Готовых русскоязычных моделей у OpenMed нет, но архитектура и рецепт обучения открыты — значит, модель можно адаптировать под русский клинический текст самостоятельно. Ниже воспроизводимый путь от сырых данных до модели, подключённой к сервису. Ориентир по срокам: пилотная модель — 2–4 недели работы ML-инженера, доведение до продакшена дольше.
- Данные: русский клинический текст — выписки, протоколы, анамнезы. Для NER хватает нескольких тысяч размеченных предложений на старт, для устойчивого PII нужно больше и с примерами всех типов идентификаторов.
- Железо: одна GPU на 24 ГБ (RTX 3090/4090, A10) закрывает LoRA-дообучение. Для полноценного domain-adaptive pretraining желательно больше памяти или несколько карт.
- Стек: Python и библиотеки
transformers,datasets,peft,accelerate,seqeval.
pip install transformers datasets peft accelerate seqevalАнглоязычные веса OpenMed для русского не подойдут как есть — нужна база, которая уже видела русский язык. Разумные варианты:
| База | Когда брать |
| DeepPavlov/rubert-base-cased | Русскоязычная база общего домена, хорошая точка старта |
| xlm-roberta-base / large | Мультиязычная, если корпус смешанный (русский + английский) |
| Русские биомед-энкодеры | Если найдёте предобученную на медицинском русском — лучший старт |
Архитектура OpenMed для NER — это токен-классификация поверх энкодера, поэтому рецепт переносится на любую из этих баз один в один.
Разметка ведётся в BIO-схеме: B- — начало сущности, I- — продолжение, O — вне сущности. Удобные инструменты — Label Studio или Doccano. Формат хранения — CoNLL (токен и метка через пробел, предложения разделены пустой строкой):
Пациент O
жалуется O
на O
головную B-SYMPTOM
боль I-SYMPTOM
, O
назначен O
эналаприл B-DRUGСразу закладывайте в набор меток и клинические сущности (DISEASE, DRUG, SYMPTOM, ANATOMY), и российские идентификаторы для PII (SNILS, OMS, PASSPORT, MED_RECORD).
Если неразмеченного русского медтекста много, сначала дообучите базу на задаче masked language modeling — модель «привыкнет» к терминологии до разметки. Это и есть DAPT из статьи OpenMed. Шаг можно пропустить, если размеченных данных достаточно, и сразу идти к LoRA.
from transformers import AutoModelForMaskedLM, AutoTokenizer, DataCollatorForLanguageModeling
# Дообучение base на неразмеченном русском мед-корпусе через MLM,
# затем сохранённый чекпойнт используется как база для Шага 4.LoRA обучает лишь малую долю весов — быстро, дёшево по памяти и без риска «сломать» базу.
from transformers import (
AutoModelForTokenClassification, AutoTokenizer,
TrainingArguments, Trainer, DataCollatorForTokenClassification,
)
from peft import LoraConfig, get_peft_model, TaskType
base = "DeepPavlov/rubert-base-cased"
tokenizer = AutoTokenizer.from_pretrained(base)
model = AutoModelForTokenClassification.from_pretrained(
base, num_labels=len(label_list), id2label=id2label, label2id=label2id,
)
lora = LoraConfig(
task_type=TaskType.TOKEN_CLS,
r=16, lora_alpha=32, lora_dropout=0.1,
target_modules=["query", "value"],
)
model = get_peft_model(model, lora)
model.print_trainable_parameters() # обучается менее 1,5% весов (как в статье OpenMed)
args = TrainingArguments(
output_dir="openmed-ru-ner",
learning_rate=2e-4,
per_device_train_batch_size=16,
num_train_epochs=5,
eval_strategy="epoch",
save_strategy="epoch",
)
trainer = Trainer(
model=model, args=args,
train_dataset=train_ds, eval_dataset=val_ds,
tokenizer=tokenizer,
data_collator=DataCollatorForTokenClassification(tokenizer),
)
trainer.train()
model.save_pretrained("openmed-ru-ner")Важная деталь: при токенизации метки нужно выравнивать по субтокенам (первому субтокену слова — реальная метка, остальным -100), иначе обучение поедет.
СНИЛС, полис ОМС и паспорт имеют жёсткий формат, поэтому гибрид «модель + регулярные выражения» работает надёжнее и дешевле, чем одна модель:
import re
PATTERNS = {
"SNILS": r"\b\d{3}-\d{3}-\d{3} \d{2}\b",
"OMS": r"\b\d{16}\b",
"PASSPORT": r"\b\d{2} ?\d{2} \d{6}\b",
}
def mask_ru_pii(text: str) -> str:
for label, pattern in PATTERNS.items():
text = re.sub(pattern, f"[{label}]", text)
return textРегулярками закрываете структурированные идентификаторы, а обученной моделью — свободный текст (имена, адреса, даты).
Метрика для NER — F1 по сущностям (не по токенам), считается через seqeval. Держите отдельный held-out набор, который модель не видела при обучении:
from seqeval.metrics import classification_report
print(classification_report(true_labels, pred_labels))Ориентир: сначала добейтесь приемлемого F1 на частых сущностях (DISEASE, DRUG), затем прицельно докидывайте примеры туда, где модель проседает.
Дообученная модель — это стандартный чекпойнт transformers, поэтому её можно отдавать через тот же REST-слой OpenMed (Шаг «Подключение и интеграция»), указав путь к своей модели вместо англоязычной. Так русский NER/PII встаёт в уже готовый пайплайн /analyze и /pii/deidentify.
Полезные ссылки
- Сайт: openmed.life
- Документация: openmed.life/docs
- GitHub: github.com/maziyarpanahi/openmed
- Модели на Hugging Face: huggingface.co/OpenMed
- Пакет PyPI: pypi.org/project/openmed
- Научная статья: arxiv.org/abs/2508.01630
По теме
Если вы работаете с медицинскими данными и хотите обрабатывать их локально, без передачи в облако, OpenMed станет хорошей отправной точкой для приватного контура.
Если захотите обсудить, как это применить у себя или в команде — пишите в Telegram @pimenov
Если хотите разобрать свою задачу — напишите мне Если хотите разобрать свою задачу — напишите мне.
Можно прийти с идеей, черновым контекстом или уже живой задачей. Помогу быстро понять, где реальный следующий шаг, а где лишний шум.
Обычно хватает 2–3 сообщений, чтобы понять, могу ли я здесь реально помочь и в каком формате лучше двигаться дальше.