Views
No views yet

transformers implementation of the original Kosmos-2 model from Microsoft.1import requests
2
3from PIL import Image
4from transformers import AutoProcessor, AutoModelForVision2Seq
5
6
7model = AutoModelForVision2Seq.from_pretrained("microsoft/kosmos-2-patch14-224")
8processor = AutoProcessor.from_pretrained("microsoft/kosmos-2-patch14-224")
9
10prompt = "<grounding>An image of"
11
12url = "https://huggingface.co/microsoft/kosmos-2-patch14-224/resolve/main/snowman.png"
13image = Image.open(requests.get(url, stream=True).raw)
14
15# The original Kosmos-2 demo saves the image first then reload it. For some images, this will give slightly different image input and change the generation outputs.
16image.save("new_image.jpg")
17image = Image.open("new_image.jpg")
18
19inputs = processor(text=prompt, images=image, return_tensors="pt")
20
21generated_ids = model.generate(
22 pixel_values=inputs["pixel_values"],
23 input_ids=inputs["input_ids"],
24 attention_mask=inputs["attention_mask"],
25 image_embeds=None,
26 image_embeds_position_mask=inputs["image_embeds_position_mask"],
27 use_cache=True,
28 max_new_tokens=128,
29)
30generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
31
32# Specify `cleanup_and_extract=False` in order to see the raw model generation.
33processed_text = processor.post_process_generation(generated_text, cleanup_and_extract=False)
34
35print(processed_text)
36# `<grounding> An image of<phrase> a snowman</phrase><object><patch_index_0044><patch_index_0863></object> warming himself by<phrase> a fire</phrase><object><patch_index_0005><patch_index_0911></object>.`
37
38# By default, the generated text is cleanup and the entities are extracted.
39processed_text, entities = processor.post_process_generation(generated_text)
40
41print(processed_text)
42# `An image of a snowman warming himself by a fire.`
43
44print(entities)
45# `[('a snowman', (12, 21), [(0.390625, 0.046875, 0.984375, 0.828125)]), ('a fire', (41, 47), [(0.171875, 0.015625, 0.484375, 0.890625)])]`
461import requests
2
3from PIL import Image
4from transformers import AutoProcessor, AutoModelForVision2Seq
5
6
7model = AutoModelForVision2Seq.from_pretrained("microsoft/kosmos-2-patch14-224")
8processor = AutoProcessor.from_pretrained("microsoft/kosmos-2-patch14-224")
9
10url = "https://huggingface.co/microsoft/kosmos-2-patch14-224/resolve/main/snowman.png"
11image = Image.open(requests.get(url, stream=True).raw)
12
13def run_example(prompt):
14
15 inputs = processor(text=prompt, images=image, return_tensors="pt")
16 generated_ids = model.generate(
17 pixel_values=inputs["pixel_values"],
18 input_ids=inputs["input_ids"],
19 attention_mask=inputs["attention_mask"],
20 image_embeds=None,
21 image_embeds_position_mask=inputs["image_embeds_position_mask"],
22 use_cache=True,
23 max_new_tokens=128,
24 )
25 generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
26 _processed_text = processor.post_process_generation(generated_text, cleanup_and_extract=False)
27 processed_text, entities = processor.post_process_generation(generated_text)
28
29 print(processed_text)
30 print(entities)
31 print(_processed_text)Kosmos-2 could perform:1prompt = "<grounding><phrase> a snowman</phrase>"
2run_example(prompt)
3
4# a snowman is warming himself by the fire
5# [('a snowman', (0, 9), [(0.390625, 0.046875, 0.984375, 0.828125)]), ('the fire', (32, 40), [(0.203125, 0.015625, 0.453125, 0.859375)])]
6
7# <grounding><phrase> a snowman</phrase><object><patch_index_0044><patch_index_0863></object> is warming himself by<phrase> the fire</phrase><object><patch_index_0006><patch_index_0878></object>1prompt = "<grounding><phrase> a snowman next to a fire</phrase>"
2run_example(prompt)
3
4# a snowman next to a fire
5# [('a snowman next to a fire', (0, 24), [(0.390625, 0.046875, 0.984375, 0.828125)])]
6
7# <grounding><phrase> a snowman next to a fire</phrase><object><patch_index_0044><patch_index_0863></object>1prompt = "<grounding><phrase> It</phrase><object><patch_index_0044><patch_index_0863></object> is"
2run_example(prompt)
3
4# It is snowman in a hat and scarf
5# [('It', (0, 2), [(0.390625, 0.046875, 0.984375, 0.828125)])]
6
7# <grounding><phrase> It</phrase><object><patch_index_0044><patch_index_0863></object> is snowman in a hat and scarf1prompt = "<grounding> Question: What is special about this image? Answer:"
2run_example(prompt)
3
4# Question: What is special about this image? Answer: The image features a snowman sitting by a campfire in the snow.
5# [('a snowman', (71, 80), [(0.390625, 0.046875, 0.984375, 0.828125)]), ('a campfire', (92, 102), [(0.109375, 0.640625, 0.546875, 0.984375)])]
6
7# <grounding> Question: What is special about this image? Answer: The image features<phrase> a snowman</phrase><object><patch_index_0044><patch_index_0863></object> sitting by<phrase> a campfire</phrase><object><patch_index_0643><patch_index_1009></object> in the snow.1prompt = "<grounding> Question: Where is<phrase> the fire</phrase><object><patch_index_0005><patch_index_0911></object> next to? Answer:"
2run_example(prompt)
3
4# Question: Where is the fire next to? Answer: Near the snowman.
5# [('the fire', (19, 27), [(0.171875, 0.015625, 0.484375, 0.890625)]), ('the snowman', (50, 61), [(0.390625, 0.046875, 0.984375, 0.828125)])]
6
7# <grounding> Question: Where is<phrase> the fire</phrase><object><patch_index_0005><patch_index_0911></object> next to? Answer: Near<phrase> the snowman</phrase><object><patch_index_0044><patch_index_0863></object>.1prompt = "<grounding> An image of"
2run_example(prompt)
3
4# An image of a snowman warming himself by a campfire.
5# [('a snowman', (12, 21), [(0.390625, 0.046875, 0.984375, 0.828125)]), ('a campfire', (41, 51), [(0.109375, 0.640625, 0.546875, 0.984375)])]
6
7# <grounding> An image of<phrase> a snowman</phrase><object><patch_index_0044><patch_index_0863></object> warming himself by<phrase> a campfire</phrase><object><patch_index_0643><patch_index_1009></object>.1prompt = "<grounding> Describe this image in detail:"
2run_example(prompt)
3
4# Describe this image in detail: The image features a snowman sitting by a campfire in the snow. He is wearing a hat, scarf, and gloves, with a pot nearby and a cup nearby. The snowman appears to be enjoying the warmth of the fire, and it appears to have a warm and cozy atmosphere.
5# [('a campfire', (71, 81), [(0.171875, 0.015625, 0.484375, 0.984375)]), ('a hat', (109, 114), [(0.515625, 0.046875, 0.828125, 0.234375)]), ('scarf', (116, 121), [(0.515625, 0.234375, 0.890625, 0.578125)]), ('gloves', (127, 133), [(0.515625, 0.390625, 0.640625, 0.515625)]), ('a pot', (140, 145), [(0.078125, 0.609375, 0.265625, 0.859375)]), ('a cup', (157, 162), [(0.890625, 0.765625, 0.984375, 0.984375)])]
6
7# <grounding> Describe this image in detail: The image features a snowman sitting by<phrase> a campfire</phrase><object><patch_index_0005><patch_index_1007></object> in the snow. He is wearing<phrase> a hat</phrase><object><patch_index_0048><patch_index_0250></object>,<phrase> scarf</phrase><object><patch_index_0240><patch_index_0604></object>, and<phrase> gloves</phrase><object><patch_index_0400><patch_index_0532></object>, with<phrase> a pot</phrase><object><patch_index_0610><patch_index_0872></object> nearby and<phrase> a cup</phrase><object><patch_index_0796><patch_index_1023></object> nearby. The snowman appears to be enjoying the warmth of the fire, and it appears to have a warm and cozy atmosphere.entities, you can use the following helper function to draw their bounding bboxes on the image:1import cv2
2import numpy as np
3import os
4import requests
5import torch
6import torchvision.transforms as T
7
8from PIL import Image
9
10
11def is_overlapping(rect1, rect2):
12 x1, y1, x2, y2 = rect1
13 x3, y3, x4, y4 = rect2
14 return not (x2 < x3 or x1 > x4 or y2 < y3 or y1 > y4)
15
16
17def draw_entity_boxes_on_image(image, entities, show=False, save_path=None):
18 """_summary_
19 Args:
20 image (_type_): image or image path
21 collect_entity_location (_type_): _description_
22 """
23 if isinstance(image, Image.Image):
24 image_h = image.height
25 image_w = image.width
26 image = np.array(image)[:, :, [2, 1, 0]]
27 elif isinstance(image, str):
28 if os.path.exists(image):
29 pil_img = Image.open(image).convert("RGB")
30 image = np.array(pil_img)[:, :, [2, 1, 0]]
31 image_h = pil_img.height
32 image_w = pil_img.width
33 else:
34 raise ValueError(f"invaild image path, {image}")
35 elif isinstance(image, torch.Tensor):
36 image_tensor = image.cpu()
37 reverse_norm_mean = torch.tensor([0.48145466, 0.4578275, 0.40821073])[:, None, None]
38 reverse_norm_std = torch.tensor([0.26862954, 0.26130258, 0.27577711])[:, None, None]
39 image_tensor = image_tensor * reverse_norm_std + reverse_norm_mean
40 pil_img = T.ToPILImage()(image_tensor)
41 image_h = pil_img.height
42 image_w = pil_img.width
43 image = np.array(pil_img)[:, :, [2, 1, 0]]
44 else:
45 raise ValueError(f"invaild image format, {type(image)} for {image}")
46
47 if len(entities) == 0:
48 return image
49
50 new_image = image.copy()
51 previous_bboxes = []
52 # size of text
53 text_size = 1
54 # thickness of text
55 text_line = 1 # int(max(1 * min(image_h, image_w) / 512, 1))
56 box_line = 3
57 (c_width, text_height), _ = cv2.getTextSize("F", cv2.FONT_HERSHEY_COMPLEX, text_size, text_line)
58 base_height = int(text_height * 0.675)
59 text_offset_original = text_height - base_height
60 text_spaces = 3
61
62 for entity_name, (start, end), bboxes in entities:
63 for (x1_norm, y1_norm, x2_norm, y2_norm) in bboxes:
64 orig_x1, orig_y1, orig_x2, orig_y2 = int(x1_norm * image_w), int(y1_norm * image_h), int(x2_norm * image_w), int(y2_norm * image_h)
65 # draw bbox
66 # random color
67 color = tuple(np.random.randint(0, 255, size=3).tolist())
68 new_image = cv2.rectangle(new_image, (orig_x1, orig_y1), (orig_x2, orig_y2), color, box_line)
69
70 l_o, r_o = box_line // 2 + box_line % 2, box_line // 2 + box_line % 2 + 1
71
72 x1 = orig_x1 - l_o
73 y1 = orig_y1 - l_o
74
75 if y1 < text_height + text_offset_original + 2 * text_spaces:
76 y1 = orig_y1 + r_o + text_height + text_offset_original + 2 * text_spaces
77 x1 = orig_x1 + r_o
78
79 # add text background
80 (text_width, text_height), _ = cv2.getTextSize(f" {entity_name}", cv2.FONT_HERSHEY_COMPLEX, text_size, text_line)
81 text_bg_x1, text_bg_y1, text_bg_x2, text_bg_y2 = x1, y1 - (text_height + text_offset_original + 2 * text_spaces), x1 + text_width, y1
82
83 for prev_bbox in previous_bboxes:
84 while is_overlapping((text_bg_x1, text_bg_y1, text_bg_x2, text_bg_y2), prev_bbox):
85 text_bg_y1 += (text_height + text_offset_original + 2 * text_spaces)
86 text_bg_y2 += (text_height + text_offset_original + 2 * text_spaces)
87 y1 += (text_height + text_offset_original + 2 * text_spaces)
88
89 if text_bg_y2 >= image_h:
90 text_bg_y1 = max(0, image_h - (text_height + text_offset_original + 2 * text_spaces))
91 text_bg_y2 = image_h
92 y1 = image_h
93 break
94
95 alpha = 0.5
96 for i in range(text_bg_y1, text_bg_y2):
97 for j in range(text_bg_x1, text_bg_x2):
98 if i < image_h and j < image_w:
99 if j < text_bg_x1 + 1.35 * c_width:
100 # original color
101 bg_color = color
102 else:
103 # white
104 bg_color = [255, 255, 255]
105 new_image[i, j] = (alpha * new_image[i, j] + (1 - alpha) * np.array(bg_color)).astype(np.uint8)
106
107 cv2.putText(
108 new_image, f" {entity_name}", (x1, y1 - text_offset_original - 1 * text_spaces), cv2.FONT_HERSHEY_COMPLEX, text_size, (0, 0, 0), text_line, cv2.LINE_AA
109 )
110 # previous_locations.append((x1, y1))
111 previous_bboxes.append((text_bg_x1, text_bg_y1, text_bg_x2, text_bg_y2))
112
113 pil_image = Image.fromarray(new_image[:, :, [2, 1, 0]])
114 if save_path:
115 pil_image.save(save_path)
116 if show:
117 pil_image.show()
118
119 return new_image
120
121
122# (The same image from the previous code example)
123url = "https://huggingface.co/microsoft/kosmos-2-patch14-224/resolve/main/snowman.png"
124image = Image.open(requests.get(url, stream=True).raw)
125
126# From the previous code example
127entities = [('a snowman', (12, 21), [(0.390625, 0.046875, 0.984375, 0.828125)]), ('a fire', (41, 47), [(0.171875, 0.015625, 0.484375, 0.890625)])]
128
129# Draw the bounding bboxes
130draw_entity_boxes_on_image(image, entities, show=True)@article{kosmos-2,
title={Kosmos-2: Grounding Multimodal Large Language Models to the World},
author={Zhiliang Peng and Wenhui Wang and Li Dong and Yaru Hao and Shaohan Huang and Shuming Ma and Furu Wei},
journal={ArXiv},
year={2023},
volume={abs/2306}
}
@article{kosmos-1,
title={Language Is Not All You Need: Aligning Perception with Language Models},
author={Shaohan Huang and Li Dong and Wenhui Wang and Yaru Hao and Saksham Singhal and Shuming Ma and Tengchao Lv and Lei Cui and Owais Khan Mohammed and Qiang Liu and Kriti Aggarwal and Zewen Chi and Johan Bjorck and Vishrav Chaudhary and Subhojit Som and Xia Song and Furu Wei},
journal={ArXiv},
year={2023},
volume={abs/2302.14045}
}
@article{metalm,
title={Language Models are General-Purpose Interfaces},
author={Yaru Hao and Haoyu Song and Li Dong and Shaohan Huang and Zewen Chi and Wenhui Wang and Shuming Ma and Furu Wei},
journal={ArXiv},
year={2022},
volume={abs/2206.06336}
}