Views
No views yet
<think>...</think> tokens before writing out its final answer. In general, the model has a tendency to think longer for harder or ill-defined questions, while sticking to shorter reasoning traces for easier queries.pip install transformers==4.57.1 accelerate==1.12.0 torchvision==0.24.1 qwen-vl-utils==0.0.14transformers and qwen_vl_utils:1import torch
2from transformers import Qwen3VLForConditionalGeneration, AutoTokenizer, AutoProcessor
3from qwen_vl_utils import process_vision_info
4
5# default: Load the model on the available device(s)
6model = Qwen3VLForConditionalGeneration.from_pretrained(
7 "OctoMed/OctoMed-4B", dtype=torch.bfloat16, device_map="auto"
8)
9
10# We recommend enabling flash_attention_2 for better acceleration and memory saving, especially in multi-image and video scenarios.
11# model = Qwen3VLForConditionalGeneration.from_pretrained(
12# "OctoMed/OctoMed-4B",
13# dtype=torch.bfloat16,
14# attn_implementation="flash_attention_2",
15# device_map="auto",
16# )
17
18# The default range for the number of visual tokens per image in the model is 4-16384.
19# You can set min_pixels and max_pixels according to your needs, such as a token range of 256-1280, to balance performance and cost.
20min_pixels = 262144
21max_pixels = 262144
22processor = AutoProcessor.from_pretrained("OctoMed/OctoMed-4B", min_pixels=min_pixels, max_pixels=max_pixels)
23
24# Text-Only Query
25# messages = [
26# {
27# "role": "user",
28# "content": [
29# {"type": "text", "text": "I've had a persistent dry cough for two weeks but no fever. Could this be allergies, and when should I see a doctor?"},
30# ],
31# }
32# ]
33
34# General Query
35# messages = [
36# {
37# "role": "user",
38# "content": [
39# {
40# "type": "image",
41# "image": "https://cdn.ncbi.nlm.nih.gov/pmc/blobs/51b2/10835941/13323b55fbb5/13256_2024_4349_Fig1_HTML.jpg",
42# },
43# {"type": "text", "text": "Describe this image."},
44# ],
45# }
46# ]
47
48# Multiple Choice Query
49messages = [
50 {
51 "role": "user",
52 "content": [
53 {
54 "type": "image",
55 "image": "https://cdn.ncbi.nlm.nih.gov/pmc/blobs/51b2/10835941/13323b55fbb5/13256_2024_4349_Fig1_HTML.jpg",
56 },
57 {"type": "text", "text": "What orientation was the MRI in image B taken in?\nA. Axial\nB. Coronal\nC. Sagittal\nD. Oblique\n\nPlease reason step-by-step, and put your final answer within \\boxed{}."},
58 ],
59 }
60]
61
62# Preparation for inference
63text = processor.apply_chat_template(
64 messages, tokenize=False, add_generation_prompt=True
65)
66image_inputs, video_inputs = process_vision_info(messages)
67inputs = processor(
68 text=[text],
69 images=image_inputs,
70 videos=video_inputs,
71 padding=True,
72 return_tensors="pt",
73)
74
75inputs = inputs.to(device="cuda")
76
77# Inference: Generation of the output
78generated_ids = model.generate(**inputs, max_new_tokens=8192)
79generated_ids_trimmed = [
80 out_ids[len(in_ids) :] for in_ids, out_ids in zip(inputs.input_ids, generated_ids)
81]
82output_text = processor.batch_decode(
83 generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False
84)
85print(output_text)1from vllm import LLM, SamplingParams
2from transformers import AutoProcessor
3
4min_pixels = 262144
5max_pixels = 262144
6processor = AutoProcessor.from_pretrained("OctoMed/OctoMed-4B", min_pixels=min_pixels, max_pixels=max_pixels)
7
8llm = LLM(
9 model="OctoMed/OctoMed-4B",
10 trust_remote_code=True,
11 dtype="bfloat16",
12 max_model_len=8192,
13 tensor_parallel_size=4,
14 gpu_memory_utilization=0.8,
15 limit_mm_per_prompt={"image": 1}
16)
17
18# Set up sampling parameters
19sampling_params = SamplingParams(
20 temperature=0.6,
21 top_p=0.95,
22 max_tokens=8192,
23)
24
25image_data = []
26
27# Text-Only Query
28messages = [
29 {
30 "role": "user",
31 "content": [
32 {"type": "text", "text": "Explain the difference between type 1 and type 2 diabetes."},
33 ],
34 }
35]
36
37# General Query
38# image_data = ['https://cdn.ncbi.nlm.nih.gov/pmc/blobs/51b2/10835941/13323b55fbb5/13256_2024_4349_Fig1_HTML.jpg']
39# messages = [
40# {
41# "role": "user",
42# "content": [
43# {
44# "type": "image",
45# "image": image_data[0],
46# },
47# {"type": "text", "text": "Describe this image."},
48# ],
49# }
50# ]
51
52# Multiple Choice Query
53# image_data = ['https://cdn.ncbi.nlm.nih.gov/pmc/blobs/51b2/10835941/13323b55fbb5/13256_2024_4349_Fig1_HTML.jpg']
54# messages = [
55# {
56# "role": "user",
57# "content": [
58# {
59# "type": "image",
60# "image": image_data[0],
61# },
62# {"type": "text", "text": "What orientation was the MRI in image B taken in?\nA. Axial\nB. Coronal\nC. Sagittal\nD. Oblique\n\nPlease reason step-by-step, and put your final answer within \\boxed{}."},
63# ],
64# }
65# ]
66
67prompt = processor.apply_chat_template(
68 messages, tokenize=False, add_generation_prompt=True)
69
70if image_data:
71 mm_prompt = {
72 "prompt": prompt,
73 "multi_modal_data": {"image": image_data}
74 }
75else:
76 mm_prompt = {"prompt": prompt}
77
78# Generate response
79outputs = llm.generate([mm_prompt], sampling_params)
80
81# Print the generated response
82for output in outputs:
83 prompt = output.prompt
84 generated_text = output.outputs[0].text
85 print(f"Prompt: {prompt}")
86 print(f"Generated text: {generated_text}")
87 print("-" * 50){optional image(s)}
{question}
{options, 1 on each line}
Please reason step-by-step, and put your final answer within \boxed{}.{image(s)}
What orientation was the MRI in image B taken in?
A: Axial
B: Coronal
C: Sagittal
D: Oblique
Please reason step-by-step, and put your final answer within \boxed{}.\boxed{}.1@article{ossowski2025octomed,
2 title={OctoMed: Data Recipes for State-of-the-Art Multimodal Medical Reasoning},
3 author={Ossowski, Timothy and Zhang, Sheng and Liu, Qianchu and Qin, Guanghui and Tan, Reuben and Naumann, Tristan and Hu, Junjie and Poon, Hoifung},
4 journal={arXiv preprint arXiv:2511.23269},
5 year={2025}
6}