TL;DR для торопыжек
25 февраля — финал The MedGemma Impact Challenge на Kaggle. Я уже несколько недель копаюсь в этой медицинской модели от Google, пытаясь выжать из неё что-то крутое для конкурса. Пока идеальное решение где-то между "гениально" и "зачем я это делаю в 3 ночи", решил поделиться тем, как вообще эта штука работает и что с ней можно делать.
Спойлер: она умеет не только отвечать "идите к врачу" на любой симптом 🏥
Почему я вообще за это взялся?
Есть такая штука — MedGemma. Google взяли свою Gemma, скормили ей всю медицинскую литературу (наверное, включая инструкции к валидолу), и получилась модель, которая:
Понимает, что HbA1c — это не новая криптовалюта
Может анализировать симптомы без паники
Работает на обычной RTX 4060 (привет, майнерам прошлых лет)
Отвечает на русском без потери в качестве
И вот на Kaggle запустили челлендж с призовым фондом, а я подумал: "Сколько ещё можно писать скрипты для парсинга? Пора спасать человечество с помощью AI!"
Три недели спустя я уже знаю о тензорах в bfloat16 больше, чем о своём давлении. Но кое-что интересное удалось выяснить.
Что это вообще такое?
MedGemma — это не просто "ChatGPT для медицины". Это специально обученная модель, которая:
Реально знает медицину — её учили не на Stack Overflow, а на PubMed и медицинских учебниках
Мультимодальная — понимает и текст, и картинки (представьте, может анализировать рентген!)
Локальная — работает у вас на компе, никуда не сливая ваши медицинские данные
Весит разумно — 4B параметров, а не 175B как некоторые
Важный дисклеймер: это не медицинский прибор, не лицензированный софт для диагностики, и вообще всегда консультируйтесь с врачом. Но для исследований и прототипов — самое то.
Запускаем локально (да, на вашей RTX!)
Проверяем, есть ли у нас GPU
Первым делом убеждаемся, что видеокарта не ушла на майнинг:
import torch, gc
gc.collect()
if torch.cuda.is_available():
torch.cuda.empty_cache()
print(f"GPU: {torch.cuda.get_device_name(0)} | "
f"{torch.cuda.get_device_properties(0).total_memory/1e9:.1f} GB")
else:
print("Эх, придётся на CPU... Иди чай поставь на часик")
У меня вывод такой:
GPU: NVIDIA GeForce RTX 4060 Laptop GPU | 8.6 GB
8.6 гигов — в самый раз. На 4 гига уже будет грустно, на 16+ — вообще красота.
Грузим модель (осторожно, тяжело!)
from transformers import AutoProcessor, AutoModelForImageTextToText
import time
MODEL_ID = "google/medgemma-4b-it"
print(f"Loading {MODEL_ID}...")
print("(Самое время проверить почту, это займёт ~10 секунд)")
start = time.time()
model = AutoModelForImageTextToText.from_pretrained(
MODEL_ID,
torch_dtype=torch.bfloat16, # bfloat16 — магия для экономии памяти
device_map="auto" # auto = "разберись сам, умная библиотека"
)
processor = AutoProcessor.from_pretrained(MODEL_ID)
print(f"✅ Загрузилось за {time.time()-start:.1f}s")
print(f"💾 GPU занято: {torch.cuda.memory_allocated()/1e9:.2f} GB")
print("🎉 Можно работать!")
Мой результат:
✅ Загрузилось за 6.7s
💾 GPU занято: 8.63 GB
🎉 Можно работать!
Если у вас загрузка падает с CUDA out of memory — поздравляю, вы в клубе "пора обновляться". Можно попробовать квантизацию до int8, но это отдельная история.
Функция для общения с моделью
Чтобы каждый раз не писать километры кода, делаем helper:
def ask(prompt, tokens=300):
"""
Спросить у MedGemma что-нибудь умное
Args:
prompt: ваш вопрос (можно на русском!)
tokens: сколько максимум слов в ответе
Returns:
str: ответ модели (надеюсь, адекватный)
"""
messages = [{
"role": "user",
"content": [{"type": "text", "text": prompt}]
}]
inputs = processor.apply_chat_template(
messages,
add_generation_prompt=True,
tokenize=True,
return_dict=True,
return_tensors="pt"
).to(model.device, dtype=torch.bfloat16)
with torch.inference_mode():
outputs = model.generate(
**inputs,
max_new_tokens=tokens,
do_sample=False # детерминированные ответы
)
return processor.decode(
outputs[0][inputs["input_ids"].shape[-1]:],
skip_special_tokens=True
).strip()
Гоняем тесты (и офигеваем от результатов)
Тест 1: Базовая проверка на адекватность
print("🩺 Спрашиваю про гипертензию...")
print("─" * 50)
print(ask("What is hypertension? Answer briefly."))
Ответ:
Hypertension is a condition in which the blood pressure
in the arteries is persistently elevated.
Ок, модель не галлюцинирует, что гипертензия — это новый вид йоги. Годится.
Тест 2: А по-русски слабо?
print("🩺 Теперь по-русски...")
print("─" * 50)
print(ask("Что такое гипертензия и каковы её основные причины?"))
Ответ (сокращённо):
Гипертензия (высокое кровяное давление) - это состояние,
при котором кровяное давление в артериях постоянно повышено.
Основные причины:
- Генетическая предрасположенность
- Образ жизни: неправильное питание, недостаток физической активности
- Возраст: с возрастом риск увеличивается
- Сопутствующие заболевания: диабет, болезни почек
- Стресс: хронический стресс может способствовать повышению давления
Вот это поворот! Модель не просто перевела, а дала структурированный ответ с маркированным списком. Кто-то в Google явно любит аккуратность.
Тест 3: Доктор Хаус режим ON
Даём модели симптомы и смотрим, что она предложит:
print("🔍 Анализируем симптомы...")
print("─" * 50)
print(ask("""Пациент: головная боль 3 дня, температура 38.5°C,
боль в горле, насморк. Какие возможные диагнозы?
Перечисли 3-4 варианта."""))
Ответ модели:
На основании предоставленной информации, возможные диагнозы:
1. Острый риносинусит (простуда): Сочетание насморка, боли в горле
и головной боли характерны для этого заболевания.
2. Грипп: Может проявляться схожими симптомами, включая головную боль,
лихорадку, боль в горле и насморк.
3. Инфекционный мононуклеоз: Хотя обычно сопровождается более выраженными
симптомами, может включать головную боль, лихорадку и боль в горле.
4. COVID-19: Может проявляться широким спектром симптомов, включая
перечисленные.
⚠️ ВАЖНО: Это лишь предположения. Для постановки точного диагноза
необходима консультация врача.
Офигеть! Модель:
Дала 4 варианта с объяснениями
Не забыла про COVID (актуально)
Добавила disclaimer про врача
Не предложила лечиться чесноком и молитвами
Для AI-модели это очень зрелое поведение.
Тест 4: Провизор в твоём ноутбуке
print("💊 Рассказываем про лекарства...")
print("─" * 50)
print(ask("Расскажи о Метформине: показания, механизм действия, побочные эффекты."))
Ответ (кратко):
Модель выдала:
✅ Показания: диабет 2 типа, преддиабет, СПКЯ, ожирение
✅ Механизм: улучшение чувствительности к инсулину, снижение выработки глюкозы печенью
✅ Побочки: ЖКТ-расстройства, дефицит B12, лактоацидоз (редко)
Это уровень ответа из хорошего медицинского справочника. Для модели на 4B параметров — впечатляет.
Тест 5: Опасные комбинации
Проверяем, понимает ли модель взаимодействие лекарств:
print("⚠️ Проверяем взаимодействия...")
print("─" * 50)
print(ask("Можно ли принимать аспирин и ибупрофен вместе? Какие риски?"))
Краткая выжимка ответа:
❌ Прием аспирина и ибупрофена вместе НЕ РЕКОМЕНДУЕТСЯ
Риски:
- Повышенный риск кровотечений (оба НПВП)
- Повреждение почек при длительном использовании
- Повреждение желудка и риск язвы
- Усиление побочных эффектов
Комбинация может быть оправдана только по назначению врача.
Модель не просто сказала "нельзя", а объяснила почему и когда всё-таки можно. Это важно.
Тест 6: Разбор анализов (самое интересное!)
Тут я проверяю, может ли модель интерпретировать результаты. Даём ей цифры из анализа крови:
print("📋 Интерпретируем анализы...")
print("─" * 50)
print(ask("""Результаты:
- Глюкоза: 7.8 ммоль/л (норма: 3.9-5.5)
- HbA1c: 6.8% (норма: <5.7%)
Что это значит?"""))
Ответ модели:
Ваши результаты анализов крови показывают, что у вас ДИАБЕТ 2 ТИПА.
📊 Глюкоза (7.8 ммоль/л):
Уровень выше нормы указывает на то, что организм не может
эффективно использовать глюкозу для энергии.
📊 HbA1c (6.8%):
Показатель среднего уровня глюкозы за последние 2-3 месяца.
Превышение нормы также указывает на диабет.
⚠️ Возможные долгосрочные осложнения:
- Сердечно-сосудистые заболевания
- Диабетическая нейропатия (повреждение нервов)
- Диабетическая нефропатия (повреждение почек)
- Диабетическая ретинопатия (повреждение глаз)
Это... это просто охренеть! Модель:
Правильно определила диагноз
Объяснила значение каждого показателя
Перечислила осложнения
Всё это — на основе двух цифр
Что я понял за три недели работы с MedGemma
Плюсы (их много)
✅ Локальность — данные не уходят в облако
✅ Скорость — ответы генерируются за секунды
✅ Русский язык — работает без костылей
✅ Структурированность — ответы как из учебника
✅ Честность — признаёт ограничения и шлёт к врачу
Минусы (их тоже хватает)
❌ Не может в контекст — не знает историю болезни
❌ Галлюцинации — редко, но бывают
❌ Нет персонализации — одинаково для всех
❌ Юридически непригодна — не медицинский прибор
❌ Требует GPU — на CPU будет медленно
Производительность на RTX 4060 Laptop
Метрика | Значение |
|---|---|
Загрузка модели | ~6.7 сек |
Потребление VRAM | 8.63 GB |
Генерация (100 токенов) | ~3-5 сек |
Температура GPU | 65-70°C |
Потребление энергии | ~80W |
Вполне рабочие цифры для ноутбука.
Идеи для Kaggle Challenge (и не только)
Пока я экспериментирую с такими направлениями:
1. Медицинский чат-бот для триажа
Бот, который задаёт правильные вопросы и определяет срочность обращения. Не ставит диагноз, а помогает понять: "это вызов скорой" или "можно записаться к терапевту на неделе".
2. Анализатор взаимодействий лекарств
Загружаешь список своих препаратов, получаешь предупреждения о возможных конфликтах. Особенно актуально для пожилых людей с кучей таблеток.
3. Переводчик медицинского языка
Врач написал в выписке непонятные термины? Модель переводит на человеческий язык без потери смысла.
4. Помощник для интерпретации анализов
Получил результаты — вставил в приложение, получил объяснение что к чему. С рекомендацией "показать врачу", естественно.
Технические детали для гиков
Почему bfloat16, а не float16?
bfloat16 (brain float) — формат от Google с такой же точностью по экспоненте, как у float32, но с меньшей мантиссой. Для языковых моделей это идеально:
Меньше памяти (2 байта вместо 4)
Меньше риск переполнения
Почти та же точность
Про квантизацию
Если 8 GB VRAM не хватает, можно загрузить модель в int8:
from transformers import BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(
load_in_8bit=True,
llm_int8_threshold=6.0
)
model = AutoModelForImageTextToText.from_pretrained(
MODEL_ID,
quantization_config=quantization_config,
device_map="auto"
)
Качество почти не страдает, зато модель влезет в 4-6 GB.
Про inference_mode vs no_grad
torch.inference_mode() быстрее, чем torch.no_grad():
Отключает autograd полностью
Оптимизирует выполнение графа
Блокирует случайные изменения весов
Для инференса всегда используйте inference_mode.
Этические вопросы (да, они важны)
Работая с медицинским AI, я постоянно думаю:
🤔 Кто отвечает за ошибки? Если модель неправильно проанализирует симптомы и человек поверит?
🤔 Доступность vs безопасность? Медицинская информация должна быть доступной, но не опасной.
🤔 Замена врачей? Нет, это инструмент для врачей, не замена им.
🤔 Приватность данных? Даже локальная модель должна работать с шифрованием.
Пока у меня больше вопросов, чем ответов. Но думаю об этом.
Полезные ссылки
Заключение
MedGemma — это не просто "ещё одна LLM". Это первая медицинская модель, которую можно запустить локально на потребительском железе и получить реально полезные результаты.
Конечно, она не заменит врача. Но может:
Помочь студентам-медикам учиться
Объяснить пациентам их анализы понятным языком
Подсказать исследователям направления поиска
Стать основой для медицинских приложений
До финала челленджа осталось несколько недель. Посмотрим, что выйдет. В любом случае, опыт работы с медицинским AI — это круто.
P.S. Если у вас есть идеи для Kaggle Challenge или вы тоже участвуете — пишите в комментах! Может, что-то замутим вместе.
P.P.S. Всегда консультируйтесь с врачом. Эта статья — для образования и экспериментов, а не медицинских советов.
P.P.P.S. Да, я действительно провёл три недели, разговаривая с AI про диабет и гипертензию. Моя поисковая история теперь выглядит как будто я самый больной человек на планете 😅
Хабр, спасибо что дочитали до конца! Ставьте плюсики, если хотите продолжение после финала челленджа.
