Views
No views yet
pillow
protobuf
sentencepiece
torch
transformers>=4.48.0,<4.521from transformers import AutoModelForCausalLM, AutoProcessor
2from pathlib import Path
3import torch
4
5model = AutoModelForCausalLM.from_pretrained("microsoft/maira-2", trust_remote_code=True)
6processor = AutoProcessor.from_pretrained("microsoft/maira-2", trust_remote_code=True)
7
8device = torch.device("cuda")
9model = model.eval()
10model = model.to(device)1import requests
2from PIL import Image
3
4def get_sample_data() -> dict[str, Image.Image | str]:
5 """
6 Download chest X-rays from IU-Xray, which we didn't train MAIRA-2 on. License is CC.
7 We modified this function from the Rad-DINO repository on Huggingface.
8 """
9 frontal_image_url = "https://openi.nlm.nih.gov/imgs/512/145/145/CXR145_IM-0290-1001.png"
10 lateral_image_url = "https://openi.nlm.nih.gov/imgs/512/145/145/CXR145_IM-0290-2001.png"
11
12 def download_and_open(url: str) -> Image.Image:
13 response = requests.get(url, headers={"User-Agent": "MAIRA-2"}, stream=True)
14 return Image.open(response.raw)
15
16 frontal_image = download_and_open(frontal_image_url)
17 lateral_image = download_and_open(lateral_image_url)
18
19 sample_data = {
20 "frontal": frontal_image,
21 "lateral": lateral_image,
22 "indication": "Dyspnea.",
23 "comparison": "None.",
24 "technique": "PA and lateral views of the chest.",
25 "phrase": "Pleural effusion." # For the phrase grounding example. This patient has pleural effusion.
26 }
27 return sample_data
28
29sample_data = get_sample_data()get_grounding=False). While generating, for non-grounded reporting use max_new_tokens=300, and for grounded reporting use max_new_tokens=450 to accommodate additional box and object tokens.1processed_inputs = processor.format_and_preprocess_reporting_input(
2 current_frontal=sample_data["frontal"],
3 current_lateral=sample_data["lateral"],
4 prior_frontal=None, # Our example has no prior
5 indication=sample_data["indication"],
6 technique=sample_data["technique"],
7 comparison=sample_data["comparison"],
8 prior_report=None, # Our example has no prior
9 return_tensors="pt",
10 get_grounding=False, # For this example we generate a non-grounded report
11)
12
13processed_inputs = processed_inputs.to(device)
14with torch.no_grad():
15 output_decoding = model.generate(
16 **processed_inputs,
17 max_new_tokens=300, # Set to 450 for grounded reporting
18 use_cache=True,
19 )
20prompt_length = processed_inputs["input_ids"].shape[-1]
21decoded_text = processor.decode(output_decoding[0][prompt_length:], skip_special_tokens=True)
22decoded_text = decoded_text.lstrip() # Findings generation completions have a single leading space
23prediction = processor.convert_output_to_plaintext_or_grounded_sequence(decoded_text)
24print("Parsed prediction:", prediction)There is a large right pleural effusion with associated right basilar atelectasis. The left lung is clear. No pneumothorax is identified. The cardiomediastinal silhouette and hilar contours are normal. There is no free air under the diaphragm. Surgical clips are noted in the right upper quadrant of the abdomen.
get_grounding=True, MAIRA-2 would generate a grounded report. For this example, that looks like this:1('There is a large right pleural effusion.', [(0.055, 0.275, 0.445, 0.665)]),
2('The left lung is clear.', None),
3('No pneumothorax is identified.', None),
4('The cardiomediastinal silhouette is within normal limits.', None),
5('The visualized osseous structures are unremarkable.', None)(x, y) coordinates of the top left and bottom right corners of the box, e.g. (x_topleft, y_topleft, x_bottomright, y_bottomright). These are relative to the cropped image (that is, the image that MAIRA-2 ultimately got as input), so be careful while visualising. The processor provides a method adjust_box_for_original_image_size to get boxes relative to the original image shape.get_sample_data) that our phrase here is just "Pleural effusion", which we already know is present in this image.1processed_inputs = processor.format_and_preprocess_phrase_grounding_input(
2 frontal_image=sample_data["frontal"],
3 phrase=sample_data["phrase"],
4 return_tensors="pt",
5)
6
7processed_inputs = processed_inputs.to(device)
8with torch.no_grad():
9 output_decoding = model.generate(
10 **processed_inputs,
11 max_new_tokens=150,
12 use_cache=True,
13 )
14prompt_length = processed_inputs["input_ids"].shape[-1]
15decoded_text = processor.decode(output_decoding[0][prompt_length:], skip_special_tokens=True)
16prediction = processor.convert_output_to_plaintext_or_grounded_sequence(decoded_text)
17
18print("Parsed prediction:", prediction)('Pleural effusion.', [(0.025, 0.345, 0.425, 0.575)])processor.adjust_box_for_original_image_size to get boxes adjusted for the original image shape.| Dataset | Country | # examples (ungrounded) | # examples (grounded) |
|---|---|---|---|
| MIMIC-CXR | USA | 55 218 | 595* |
| PadChest | Spain | 52 828 | 3 122 |
| USMix (Private) | USA | 118 031 | 53 613 |
@article{Bannur2024MAIRA2GR,
title={MAIRA-2: Grounded Radiology Report Generation},
author={Shruthi Bannur and Kenza Bouzid and Daniel C. Castro and Anton Schwaighofer and Anja Thieme and Sam Bond-Taylor and Maximilian Ilse and Fernando P\'{e}rez-Garc\'{i}a and Valentina Salvatelli and Harshita Sharma and Felix Meissen and Mercy Prasanna Ranjit and Shaury Srivastav and Julia Gong and Noel C. F. Codella and Fabian Falck and Ozan Oktay and Matthew P. Lungren and Maria T. A. Wetscherek and Javier Alvarez-Valle and Stephanie L. Hyland},
journal={arXiv},
year={2024},
volume={abs/2406.04449},
url={https://arxiv.org/abs/2406.04449}
}Bannur*, S., Bouzid*, K., Castro, D. C., Schwaighofer, A., Thieme, A., Bond-Taylor, S., Ilse, M., Pérez-García, F., Salvatelli, V., Sharma, H., Meissen, F., Ranjit, M.P., Srivastav, S., Gong, J., Codella, N.C.F., Falck, F., Oktay, O., Lungren, M.P., Wetscherek, M.T., Alvarez-Valle, J., & Hyland, S. L. (2024). MAIRA-2: Grounded Radiology Report Generation. arXiv preprint abs/2406.04449.
stephanie.hyland@microsoft.com)shruthi.bannur@microsoft.com)