OpenMed — открытый набор компактных моделей и инструментов для извлечения клинических сущностей и обезличивания медицинских текстов. Обработка выполняется на вашем устройстве или сервере; после загрузки моделей основной контур не требует облачного сервиса.

Данные и команды ниже проверены по официальной документации OpenMed 2.3.0 на 7 сентября 2026 года.

Что такое OpenMed

OpenMed объединяет модели клинического распознавания сущностей (Named Entity Recognition, NER), средства поиска персональных медицинских данных и политики обезличивания. Модели размечают фрагменты текста, а не генерируют ответы, поэтому результатом служат сущности, их позиции и оценки уверенности.

Проект распространяется по лицензии Apache-2.0. Официальный сайт сообщает о более чем 2 000 открытых моделях в 13 биомедицинских направлениях. В приведённых карточках каталога размеры моделей указаны в диапазоне 33M–568M; характеристики конкретного чекпойнта смотрите в реестре.

💡
tNER находит в тексте болезни, препараты, гены, белки, анатомические и другие клинические сущности. PII (Personally Identifiable Information) — персональные данные, по которым можно идентифицировать человека. PHI (Protected Health Information) — защищаемая медицинская информация и связанные с ней идентификаторы.

Основные возможности

ВозможностьЧто даёт
Клинический NERИзвлекает болезни, препараты, химические вещества, гены, белки, анатомию и онкологические сущности
ОбезличиваниеОбрабатывает 55+ типов PHI, включая все 18 категорий HIPAA Safe Harbor
Стратегии редактурыМаскирование, удаление, замена, хеширование, сохранение формата и сдвиг дат
Локальный запускPython на CPU или NVIDIA GPU, MLX на Apple Silicon, мобильные и браузерные среды
Пакетная обработка<code>BatchProcessor</code> обрабатывает наборы текстов и поддерживает контроль ошибок и контрольные точки
ИнтеграцииPython API, командная строка, REST, gRPC, FHIR и другие локально разворачиваемые адаптеры
АудитПороговые значения, записи диапазонов, отчёты аудита и закрытые гейты выпуска данных

Как устроен локальный контур

flowchart LR
    A[Клинический текст] --> B[OpenMed на вашем устройстве]
    B --> C[Клинические сущности]
    B --> D[Найденные PII/PHI]
    B --> E[Обезличенный текст]

После предварительной загрузки артефактов модели обработка может идти без сети. Для строгого офлайн-режима документация предлагает заранее заполнить кеш и установить <code>OPENMED_OFFLINE=1</code>.

⚠️
tЛокальный запуск сам по себе не гарантирует полное обезличивание. Перед выпуском данных проверяйте полноту обнаружения идентификаторов, утечки, границы сущностей, язык, формат документов и поведение выбранной политики на материалах вашего контура.

Установка и подключение OpenMed 2.3.0

Для воспроизводимого окружения зафиксируйте версию:

pip install --upgrade 'openmed[hf]==2.3.0'

Для Apple Silicon доступен отдельный набор зависимостей:

pip install --upgrade 'openmed[mlx]==2.3.0'

OpenMed 2.3.0 рассчитан на Python 3.11 и новее. Для FHIR-интеграции в релизе указан дополнительный набор <code>openmed[hf,fhir]</code>. Координаты пакета или контейнера могут появиться в реестрах позже исходного релиза, поэтому перед автоматическим развёртыванием проверяйте их доступность.

Для отдельного локального сервиса релиз 2.3.0 описывает REST и gRPC. Основной Python-вызов работает внутри процесса; после загрузки необходимых артефактов для него не требуется облачный сервис.

Минимальный пример 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(entity.label, entity.text, entity.confidence)

Функция принимает ключ из реестра OpenMed, полный идентификатор Hugging Face или путь к локальной модели. Она может возвращать структурированный объект, JSON, HTML или CSV.

Проверка результата

Успешный запуск должен вернуть непустой список <code>result.entities</code>. Для каждой найденной сущности проверьте как минимум:

  • метку и исходный фрагмент текста;
  • числовую оценку уверенности;
  • позиции <code>start</code> и <code>end</code>, совпадающие с исходной строкой;
  • отсутствие неожиданных сущностей на собственном контрольном наборе.

Пример из документации использует англоязычный клинический текст. Он проверяет установку и загрузку модели, но не доказывает качество на данных вашей организации.

Команды и сигнатуры в этом материале сверены с документацией; запуск в конкретной среде здесь не выполнялся. Перед использованием проверьте доступность версии, зависимостей, модельных артефактов и ресурсов на своей среде.

Извлечение и обезличивание PII

from openmed import deidentify, extract_pii

note = 'Patient John Doe, DOB 01/15/1970'

pii = extract_pii(note, lang='en')
redacted = deidentify(note, lang='en', method='mask')

print([(item.label, item.start, item.end) for item in pii.entities])
print(redacted.deidentified_text)

У <code>extract_pii()</code> порог уверенности по умолчанию равен <code>0.5</code>, у <code>deidentify()</code> — <code>0.7</code>. Умное объединение собирает разделённые токенизатором даты, телефоны и идентификаторы в целые диапазоны. По умолчанию <code>deidentify()</code> также выполняет детерминированную проверку структурированных идентификаторов через <code>use_safety_sweep=True</code>.

Если требуется обратимое преобразование, <code>deidentify()</code> поддерживает <code>keep_mapping=True</code>, а <code>reidentify()</code> восстанавливает исходные значения по сохранённому отображению. Такое отображение содержит персональные данные и требует отдельного контроля доступа и аудита.

Языки и статус русского

Официальная страница OpenMed 2.3.0 перечисляет 36 поддерживаемых кодов PII, включая <code>ru</code> и <code>uk</code>. Это существенное изменение по сравнению с прежней версией материала, где русский язык считался отсутствующим.

При этом источники расходятся в деталях:

  • главная страница в разных блоках сообщает о 33 и 34 языках с модельной поддержкой;
  • актуальная справка Python API перечисляет только <code>en</code>, <code>fr</code>, <code>de</code>, <code>it</code>, <code>es</code>, <code>nl</code>, <code>hi</code>, <code>te</code>, <code>pt</code>, <code>ar</code>, <code>ja</code> и <code>tr</code> для автоматического выбора модели;
  • часть языковых кодов может опираться на валидаторы идентификаторов, а не на полноценную модель для свободного текста.
⚠️
tНе считайте наличие <code>ru</code> в общем списке доказательством готового обезличивания русской медицинской карты. Перед внедрением проверьте модельный чекпойнт, покрытие кириллицы и полноту обнаружения имён, адресов, дат, паспортов, СНИЛС, полисов ОМС и внутренних медицинских номеров.

Реальное покрытие следует проверять через реестр моделей и собственный закрытый тестовый набор. Реестр хранит сведения о поддерживаемых письменностях, рекомендуемом пороге, размере, памяти и пригодности для устройств.

Выбор и предварительная загрузка модели

Получить сведения о модели можно из встроенного реестра:

from openmed.core.model_registry import get_model_info

info = get_model_info('disease_detection_superclinical')
print(info.description)
print(info.entity_types)
print(info.recommended_confidence)

Перед работой без сети загрузите модель:

openmed models pull disease_detection_superclinical --revision main --retries 5
export OPENMED_OFFLINE=1

После включения офлайн-режима команда выполняет только поиск в локальном кеше и не обращается к Hugging Face. Размер загрузки и ожидаемую память можно оценить через <code>openmed models size</code>.

Другие среды выполнения

  • Apple Silicon. MLX предназначен для локального запуска на Mac. Официальный сайт приводит ускорение 24–33× относительно CPU PyTorch для семейства Privacy Filter; результат зависит от модели и оборудования.
  • iPhone, iPad и Android. OpenMedKit и ONNX Runtime Mobile позволяют выполнять обработку на устройстве. OpenMedKit для Android не объявляет разрешение <code>INTERNET</code>.
  • Браузер и Node.js. Пакет <code>openmed@2.3.0</code> предоставляет ESM- и CommonJS-экспорты и использует ONNX. Для стандартной ONNX-модели документация предлагает установить <code>@huggingface/transformers</code> либо передать локальный токен-классификационный pipeline. Для браузера описан запуск через Transformers.js и WebGPU; в версии 2.3.0 исправлены сопоставление исходных позиций и обработка Unicode.
  • Серверный контур. Доступны REST и gRPC, а также контейнер <code>ghcr.io/maziyarpanahi/openmed:v2.3.0</code> после его публикации в реестре.

Полезные сценарии

Извлечение фактов из англоязычной литературы

На вход подают статьи или клинические тексты на поддерживаемом языке, выбирают модель нужного направления и получают сущности с позициями. Результат можно проверить по контрольным примерам и затем использовать для поиска, разметки корпуса или внутренней аналитики.

Сценарий не подходит для автоматического принятия диагностических или лечебных решений: OpenMed прямо относит клиническое извлечение к вспомогательному программному обеспечению.

Обезличивание перед следующим этапом обработки

Текст сначала проходит локальное обнаружение и редактирование PHI. Дальше передаётся только обезличенная версия, а отчёт аудита сохраняет сведения о найденных диапазонах и применённой политике.

Перед выпуском данных нужен отдельный тест на пропущенные идентификаторы. Ни одна система обезличивания не гарантирует нулевой остаточный риск.

Закрытый пилот для русскоязычных документов

Разверните OpenMed в изолированном контуре, проверьте в реестре наличие чекпойнта с подтверждённым покрытием кириллицы и нужных классов или укажите локальный путь к собственной модели. Соберите тестовый набор со всеми используемыми форматами документов. Отдельно измерьте полноту по именам, адресам и датам, а структурированные российские идентификаторы проверяйте валидаторами формата и контрольных сумм.

Наблюдаемый результат пилота — отчёт по каждой категории сущностей и список пропусков. Без такого отчёта выпуск реальных данных нельзя считать проверенным.

Адаптация под русский клинический корпус

OpenMed поддерживает локальное обучение, а опубликованный рецепт использует доменное предобучение и LoRA, обновляя менее 1,5% параметров. По данным проекта, полное дообучение по опубликованному эксперименту укладывалось менее чем в 12 часов на одной GPU, но это не оценка сроков для конкретного русского корпуса.

Практический порядок работы:

  1. Выберите энкодер с проверенным покрытием кириллицы.
  2. Сформируйте схему клинических и PII-меток.
  3. Разметьте данные в BIO-формате и отделите закрытый тестовый набор.
  4. При наличии большого неразмеченного корпуса выполните доменное предобучение.
  5. Дообучите токен-классификатор через LoRA.
  6. Добавьте валидаторы российских структурированных идентификаторов.
  7. Измерьте F1 по целым сущностям и отдельно оцените пропуски PII.
  8. Подключите стандартный чекпойнт <code>transformers</code> через локальный путь и повторите проверку на целевой среде выполнения.

При работе с реальными медицинскими данными заранее согласуйте применимые требования к персональным данным, врачебной тайне и локализации, а также модель угрозы, с профильными специалистами.

Ограничения и границы применения

  • Результаты требуют проверки квалифицированным специалистом и не должны автоматически запускать диагностику, лечение, выставление счетов или выпуск данных.
  • Качество зависит от языка, модели, порога уверенности, формата документа и способа экспорта модели.
  • Квантованные, мобильные и браузерные сборки нужно проверять отдельно: их показатели могут отличаться от Python-модели.
  • Загрузка моделей и явно включённые внешние интеграции остаются сетевой границей, даже если основной инференс локальный.
  • В OpenMed 2.3.0 некоторые необязательные наборы зависимостей включают NLTK 3.10.3. На 4 сентября 2026 года для CVE-2026-81726 не было исправленной версии. Не открывайте для недоверенного ввода пути импорта или экспорта модельных файлов NLTK.

Полезные ссылки

Следующий шаг

NeuralDeep — российская AI-инфраструктура на локальных моделях

Если вы проектируете закрытый контур для медицинских текстов, сначала определите языки, типы идентификаторов и измеримый порог допустимых пропусков.

Если захотите обсудить, как это применить у себя или в команде — пишите в Telegram @pimenov