Views
No views yet
git clone https://huggingface.co/ChantalPellegrini/RaDialog-interactive-radiology-report-generation1conda create -n llava_hf python=3.10
2conda activate llava_hf
3pip install pip==24.0
4conda install pytorch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2 pytorch-cuda=11.7 -c pytorch -c nvidia
5pip install -r requirements.txt1from pathlib import Path
2
3import io
4
5import requests
6import torch
7from PIL import Image
8import numpy as np
9from huggingface_hub import snapshot_download
10
11from LLAVA_Biovil.llava.mm_utils import tokenizer_image_token, get_model_name_from_path, KeywordsStoppingCriteria, remap_to_uint8
12from LLAVA_Biovil.llava.model.builder import load_pretrained_model
13from LLAVA_Biovil.llava.conversation import SeparatorStyle, conv_vicuna_v1
14
15from LLAVA_Biovil.llava.constants import IMAGE_TOKEN_INDEX
16from utils import create_chest_xray_transform_for_inference, init_chexpert_predictor
17
18
19def load_model_from_huggingface(repo_id):
20 # Download model files
21 model_path = snapshot_download(repo_id=repo_id, revision="main")
22 model_path = Path(model_path)
23
24 tokenizer, model, image_processor, context_len = load_pretrained_model(model_path, model_base='liuhaotian/llava-v1.5-7b',
25 model_name="llava-v1.5-7b-task-lora_radialog_instruct_llava_biovil_unfrozen_2e-5_5epochs_v5_checkpoint-21000", load_8bit=False, load_4bit=False)
26
27
28 return tokenizer, model, image_processor, context_len
29
30
31
32if __name__ == '__main__':
33 sample_img_path = "https://openi.nlm.nih.gov/imgs/512/294/3502/CXR3502_IM-1707-1001.png?keywords=Surgical%20Instruments,Cardiomegaly,Pulmonary%20Congestion,Diaphragm"
34
35 response = requests.get(sample_img_path)
36 image = Image.open(io.BytesIO(response.content))
37 image = remap_to_uint8(np.array(image))
38 image = Image.fromarray(image).convert("L")
39
40 tokenizer, model, image_processor, context_len = load_model_from_huggingface(repo_id="Chantal/RaDialog-interactive-radiology-report-generation")
41 cp_model, cp_class_names, cp_transforms = init_chexpert_predictor()
42
43 model.config.tokenizer_padding_side = "left"
44
45 cp_image = cp_transforms(image)
46 logits = cp_model(cp_image[None].half().cuda())
47 preds_probs = torch.sigmoid(logits)
48 preds = preds_probs > 0.5
49 pred = preds[0].cpu().numpy()
50 findings = cp_class_names[pred].tolist()
51 findings = ', '.join(findings).lower().strip()
52
53 conv = conv_vicuna_v1.copy()
54 REPORT_GEN_PROMPT = f"<image>. Predicted Findings: {findings}. You are to act as a radiologist and write the finding section of a chest x-ray radiology report for this X-ray image and the given predicted findings. Write in the style of a radiologist, write one fluent text without enumeration, be concise and don't provide explanations or reasons."
55 print("USER: ", REPORT_GEN_PROMPT)
56 conv.append_message("USER", REPORT_GEN_PROMPT)
57 conv.append_message("ASSISTANT", None)
58 text_input = conv.get_prompt()
59
60 # get the image
61 vis_transforms_biovil = create_chest_xray_transform_for_inference(512, center_crop_size=448)
62 image_tensor = vis_transforms_biovil(image).unsqueeze(0)
63
64 image_tensor = image_tensor.to(model.device, dtype=torch.bfloat16)
65 input_ids = tokenizer_image_token(text_input, tokenizer, IMAGE_TOKEN_INDEX, return_tensors='pt').unsqueeze(0).to(model.device)
66
67 stop_str = conv.sep if conv.sep_style != SeparatorStyle.TWO else conv.sep2
68 stopping_criteria = KeywordsStoppingCriteria([stop_str], tokenizer, input_ids)
69
70 # generate a report
71 with torch.inference_mode():
72 output_ids = model.generate(
73 input_ids,
74 images=image_tensor,
75 do_sample=False,
76 use_cache=True,
77 max_new_tokens=300,
78 stopping_criteria=[stopping_criteria],
79 pad_token_id=tokenizer.pad_token_id
80 )
81
82 pred = tokenizer.decode(output_ids[0, input_ids.shape[1]:]).strip().replace("</s>", "")
83 print("ASSISTANT: ", pred)
84
85 # add prediction to conversation
86 conv.messages.pop()
87 conv.append_message("ASSISTANT", pred)
88 stop_str = conv.sep if conv.sep_style != SeparatorStyle.TWO else conv.sep2
89 stopping_criteria = KeywordsStoppingCriteria([stop_str], tokenizer, input_ids)
90
91 # generate a report
92 with torch.inference_mode():
93 output_ids = model.generate(
94 input_ids,
95 images=image_tensor,
96 do_sample=False,
97 use_cache=True,
98 max_new_tokens=300,
99 stopping_criteria=[stopping_criteria],
100 pad_token_id=tokenizer.pad_token_id
101 )
102
103 pred = tokenizer.decode(output_ids[0, input_ids.shape[1]:]).strip().replace("</s>", "")
104 print("ASSISTANT: ", pred)
105
106 # add prediction to conversation
107 conv.messages.pop()
108 conv.append_message("ASSISTANT", pred)
109 conv.append_message("USER", "Translate this report to easy language for a patient to understand.")
110 conv.append_message("ASSISTANT", None)
111 text_input = conv.get_prompt()
112 print("USER: ", "Translate this report to easy language for a patient to understand.")
113
114 # generate easy language report
115 input_ids = tokenizer_image_token(text_input, tokenizer, IMAGE_TOKEN_INDEX, return_tensors='pt').unsqueeze(0).to(model.device)
116 with torch.inference_mode():
117 output_ids = model.generate(
118 input_ids,
119 images=image_tensor,
120 do_sample=False,
121 use_cache=True,
122 max_new_tokens=300,
123 stopping_criteria=[stopping_criteria],
124 pad_token_id=tokenizer.pad_token_id
125 )
126
127 pred = tokenizer.decode(output_ids[0, input_ids.shape[1]:]).strip().replace("</s>", "")
128 print("ASSISTANT: ", pred)
129@inproceedings{pellegrini2025radialog,
title={RaDialog: Large Vision-Language Models for X-Ray Reporting and Dialog-Driven Assistance},
author={Pellegrini, Chantal and {\"O}zsoy, Ege and Busam, Benjamin and Wiestler, Benedikt and Navab, Nassir and Keicher, Matthias},
booktitle={Medical Imaging with Deep Learning},
year={2025}
}