Views
No views yet
image-text-to-text1# pip install transformers accelerate
2# Inference for merged MedGemma-4B (OMAMA 256×256 Balanced)
3# Replace with your repo id:
4REPO_ID = "edziocodes/medgemma-breast-cancer"
5
6import re, torch
7from PIL import Image
8from transformers import AutoProcessor, AutoModelForImageTextToText
9
10device = "cuda" if torch.cuda.is_available() else "cpu"
11
12# (Optional) small speed win on Ampere/Hopper
13torch.backends.cuda.matmul.allow_tf32 = True
14
15processor = AutoProcessor.from_pretrained(REPO_ID)
16model = AutoModelForImageTextToText.from_pretrained(
17 REPO_ID,
18 torch_dtype=torch.bfloat16 if device == "cuda" else torch.float32,
19).to(device).eval()
20
21# --- Build the same prompt used for training ---
22PROMPT = "Classify this mammogram.\nA: NonCancer\nB: Cancer"
23
24def build_messages():
25 return [
26 {
27 "role": "user",
28 "content": [
29 {"type": "image"},
30 {"type": "text", "text": PROMPT},
31 ],
32 }
33 ]
34
35# --- Simple, forgiving post-processing to map text → label index/name ---
36NONC_RX = re.compile(r"\bnon[-\s]*cancer\b", re.I)
37CANC_RX = re.compile(r"\bcancer\b", re.I)
38
39def map_text_to_label(text: str) -> str:
40 t = text.strip()
41 # prefer explicit A/B if present
42 if re.search(r"\bA\b", t) and NONC_RX.search(t):
43 return "NonCancer"
44 if re.search(r"\bB\b", t) and CANC_RX.search(t):
45 return "Cancer"
46 # fallback by keywords
47 if CANC_RX.search(t) and not NONC_RX.search(t):
48 return "Cancer"
49 if NONC_RX.search(t):
50 return "NonCancer"
51 return f"Unparsed: {t}"
52
53# -------- Single image inference --------
54img = Image.open("example.png").convert("RGB") # your image path
55
56messages = build_messages()
57prompt = processor.apply_chat_template(messages, add_generation_prompt=True, tokenize=False)
58
59inputs = processor(text=prompt, images=img, return_tensors="pt").to(device)
60# Cast only float tensors to bf16 on GPU
61for k, v in inputs.items():
62 if torch.is_floating_point(v):
63 inputs[k] = v.to(torch.bfloat16)
64
65with torch.inference_mode():
66 out = model.generate(
67 **inputs,
68 max_new_tokens=40,
69 do_sample=False, # deterministic
70 disable_compile=True, # safer across envs
71 )
72
73# Slice off the prompt tokens before decoding (continuation only)
74prompt_len = inputs["input_ids"].shape[-1]
75text = processor.decode(out[0, prompt_len:], skip_special_tokens=True)
76print("Raw generation:", text)
77print("Predicted label:", map_text_to_label(text))
78
79# -------- (Optional) batched inference --------
80imgs = [Image.open(p).convert("RGB") for p in ["ex1.png", "ex2.png", "ex3.png"]]
81prompts = [prompt] * len(imgs)
82enc = processor(text=prompts, images=[[im] for im in imgs], return_tensors="pt", padding=True).to(device)
83
84for k, v in enc.items():
85 if torch.is_floating_point(v):
86 enc[k] = v.to(torch.bfloat16)
87
88lens = enc["attention_mask"].sum(dim=1) # per-example prompt length
89
90with torch.inference_mode():
91 outs = model.generate(**enc, max_new_tokens=40, do_sample=False, disable_compile=True)
92
93for seq, ln in zip(outs, lens.tolist()):
94 txt = processor.decode(seq[int(ln):], skip_special_tokens=True)
95 print("→", map_text_to_label(txt))1Raw generation: A: NonCancer
2Predicted label: NonCancer1@misc{medgemma-breast-cancer-2025,
2 author = {Edward Gaibor},
3 title = {MedGemma Fine-tuned for Breast Cancer Detection on Balanced OMAMA Dataset},
4 year = {2025},
5 publisher = {Hugging Face},
6 url = {https://huggingface.co/edziocodes/medgemma-breast-cancer}
7}medicalbreast_cancermammogramstrlsftbalanced_datasetlora