MedGemma 實戰:Google 醫療 AI 模型的使用方法與範例應用
Google 在 2025 年 I/O 發布了 MedGemma,這是他們第一個以醫療場景為核心設計的開源模型系列。它不是把通用 LLM 套上醫療 prompt 就出貨,而是從訓練資料到評測都針對醫療場景重新設計。這篇文章記錄我實際跑起來的過程,以及幾個我覺得有實用價值的應用場景。
MedGemma 是什麼
MedGemma 基於 Gemma 3 架構,目前有三個版本:
| 版本 | 參數 | 模態 | 適合場景 |
|---|---|---|---|
| MedGemma 4B IT | 4B | 文字 + 影像 | 醫學影像分析、多模態問答 |
| MedGemma 27B IT | 27B | 文字 | 臨床文件、醫學問答、長文推理 |
| MedPaLM 2(企業版) | — | 文字 | 企業授權,非開源 |
開源版本放在 Hugging Face:google/medgemma-4b-it 和 google/medgemma-27b-it。需要先申請存取權限(填一份使用條款表單,通常幾小時內核准)。
訓練資料重點:
- 醫學教科書與期刊
- de-identified 的醫學影像資料集(含胸部 X 光、眼底攝影、病理切片、皮膚鏡影像)
- 臨床問答資料集(MedQA、MedMCQA、PubMedQA)
環境建置
# 建議用虛擬環境
python -m venv medgemma-env
source medgemma-env/bin/activate
pip install transformers torch accelerate pillow
登入 Hugging Face(需要先在 HF 頁面申請 MedGemma 存取權):
huggingface-cli login
基本使用:文字模式(27B)
27B 的文字模型在臨床推理類任務表現最好,但需要至少 2 張 A100 或 H100:
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
model_id = "google/medgemma-27b-it"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
torch_dtype=torch.bfloat16,
device_map="auto", # 自動分配多卡
)
def ask_medical(question: str) -> str:
messages = [
{
"role": "system",
"content": (
"You are a medical AI assistant. "
"Provide accurate, evidence-based information. "
"Always recommend consulting a healthcare professional "
"for personal medical decisions."
),
},
{"role": "user", "content": question},
]
input_ids = tokenizer.apply_chat_template(
messages,
add_generation_prompt=True,
return_tensors="pt",
).to(model.device)
with torch.inference_mode():
output = model.generate(
input_ids,
max_new_tokens=512,
temperature=0.1, # 醫療場景建議低溫度,減少幻覺
do_sample=True,
)
generated = output[0][input_ids.shape[-1]:]
return tokenizer.decode(generated, skip_special_tokens=True)
# 範例
print(ask_medical("What are the first-line treatments for Type 2 diabetes?"))
記憶體優化:4-bit 量化(適合單張 A100)
from transformers import BitsAndBytesConfig
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
)
model = AutoModelForCausalLM.from_pretrained(
model_id,
quantization_config=bnb_config,
device_map="auto",
)
多模態使用:醫學影像分析(4B)
4B 版本支援影像輸入,適合跑在單張 A100 80GB 上:
from transformers import AutoProcessor, PaliGemmaForConditionalGeneration
from PIL import Image
import torch
model_id = "google/medgemma-4b-it"
processor = AutoProcessor.from_pretrained(model_id)
model = PaliGemmaForConditionalGeneration.from_pretrained(
model_id,
torch_dtype=torch.bfloat16,
device_map="cuda",
)
def analyze_medical_image(image_path: str, question: str) -> str:
image = Image.open(image_path).convert("RGB")
messages = [
{
"role": "user",
"content": [
{"type": "image", "image": image},
{"type": "text", "text": question},
],
}
]
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():
output = model.generate(
**inputs,
max_new_tokens=300,
temperature=0.1,
do_sample=True,
)
generated = output[0][inputs["input_ids"].shape[-1]:]
return processor.decode(generated, skip_special_tokens=True)
# 範例:胸部 X 光分析
result = analyze_medical_image(
"chest_xray.jpg",
"Describe any abnormalities visible in this chest X-ray."
)
print(result)
應用場景一:臨床摘要生成
把醫師的診療紀錄濃縮成結構化摘要,方便跨科交接或輸出給病患:
def generate_clinical_summary(clinical_note: str) -> str:
prompt = f"""以下是一份臨床診療紀錄,請生成結構化摘要,包含:
1. 主訴
2. 診斷
3. 治療計劃
4. 追蹤事項
診療紀錄:
{clinical_note}
請用繁體中文輸出。"""
return ask_medical(prompt)
# 範例輸入
note = """
病患,65 歲男性,主訴胸悶及呼吸困難三天,
昨夜症狀加劇。體檢:血壓 155/95 mmHg,
心率 88 次/分,SpO2 94%。
胸部 X 光顯示輕度肺水腫跡象。
BNP 升高至 450 pg/mL。
診斷:急性心臟衰竭急性發作(HFrEF)。
處置:給予靜脈注射利尿劑,低鹽飲食衛教。
安排心臟科門診追蹤。
"""
print(generate_clinical_summary(note))
應用場景二:醫學考題問答
用於醫學教育系統或執照考試輔助工具:
def answer_mcq(question: str, options: list[str]) -> dict:
options_text = "\n".join(f"{chr(65+i)}. {opt}" for i, opt in enumerate(options))
prompt = f"""以下是一道醫學選擇題,請選出最正確的答案並說明理由。
題目:{question}
選項:
{options_text}
請回答:選項字母 + 詳細解釋(包含相關生理機轉或臨床意義)"""
response = ask_medical(prompt)
return {"question": question, "answer": response}
result = answer_mcq(
"下列哪種藥物是治療急性心肌梗塞的首選抗血小板藥物?",
["Warfarin", "Aspirin", "Heparin", "Clopidogrel alone"]
)
print(result["answer"])
應用場景三:放射科報告草稿
整合影像分析與報告生成,輔助放射科醫師提升效率:
def generate_radiology_report(image_path: str, modality: str, body_part: str) -> str:
question = f"""You are assisting a radiologist.
Analyze this {modality} image of the {body_part}.
Please structure your findings as:
**TECHNIQUE:** [imaging technique]
**FINDINGS:** [detailed observations]
**IMPRESSION:** [summary and clinical significance]
Note: This is an AI-assisted draft. Final interpretation requires physician review."""
return analyze_medical_image(image_path, question)
# 使用範例
report = generate_radiology_report(
"chest_pa.jpg",
modality="PA chest X-ray",
body_part="chest"
)
print(report)
重要注意事項
這些是我踩過的坑:
幻覺問題不因「醫療」而消失:MedGemma 在藥物劑量、罕見疾病細節上仍有幻覺風險,任何輸出都需要醫師複核。
溫度設定要低:醫療場景裡
temperature=0.1比0.7安全得多,創意不是這裡需要的東西。繁體中文表現有限:MedGemma 的醫療術語訓練主要是英文,中文輸入的品質明顯低於英文輸入,建議重要查詢用英文輸入、中文輸出。
法規灰區:在台灣,AI 輔助診斷工具的使用涉及醫療法規,任何生產環境部署前請先諮詢法律與合規團隊。
存取申請:HF 頁面的申請大多當天核准,但需要填寫真實的使用目的,純學術研究和商業應用要分開說明。
總結
MedGemma 目前在我測試過的醫學問答和影像分析任務上,表現明顯優於同規模的通用模型,特別是在放射影像的結構化描述方面。如果你有醫療相關的 AI 應用需求,又希望資料留在自己的環境裡,MedGemma 是目前最值得認真評估的開源選項。
接下來我打算測試用它做病歷去識別化(de-identification)的效果,如果結果有意思會再寫一篇。
Friday