gokaygokay commited on
Commit
c300ab5
1 Parent(s): 5590fe1

joy_caption

Browse files
caption_models.py CHANGED
@@ -1,12 +1,13 @@
1
  import spaces
2
  import torch
3
  from PIL import Image
4
- from transformers import AutoProcessor, AutoModelForCausalLM, Qwen2VLForConditionalGeneration
5
  from qwen_vl_utils import process_vision_info
6
  import numpy as np
7
  import os
8
  from datetime import datetime
9
  import subprocess
 
10
 
11
  subprocess.run('pip install flash-attn --no-build-isolation', env={'FLASH_ATTENTION_SKIP_CUDA_BUILD': "TRUE"}, shell=True)
12
 
@@ -20,6 +21,45 @@ florence_processor = AutoProcessor.from_pretrained('microsoft/Florence-2-large',
20
  qwen_model = Qwen2VLForConditionalGeneration.from_pretrained("Qwen/Qwen2-VL-2B-Instruct", trust_remote_code=True, torch_dtype="auto").to(device).eval()
21
  qwen_processor = AutoProcessor.from_pretrained("Qwen/Qwen2-VL-2B-Instruct", trust_remote_code=True)
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  @spaces.GPU
24
  def florence_caption(image):
25
  if not isinstance(image, Image.Image):
@@ -91,4 +131,53 @@ def qwen_caption(image):
91
  generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False
92
  )
93
 
94
- return output_text[0]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import spaces
2
  import torch
3
  from PIL import Image
4
+ from transformers import AutoProcessor, AutoModelForCausalLM, Qwen2VLForConditionalGeneration, AutoModel, AutoTokenizer, AutoModelForCausalLM
5
  from qwen_vl_utils import process_vision_info
6
  import numpy as np
7
  import os
8
  from datetime import datetime
9
  import subprocess
10
+ import torch.nn as nn
11
 
12
  subprocess.run('pip install flash-attn --no-build-isolation', env={'FLASH_ATTENTION_SKIP_CUDA_BUILD': "TRUE"}, shell=True)
13
 
 
21
  qwen_model = Qwen2VLForConditionalGeneration.from_pretrained("Qwen/Qwen2-VL-2B-Instruct", trust_remote_code=True, torch_dtype="auto").to(device).eval()
22
  qwen_processor = AutoProcessor.from_pretrained("Qwen/Qwen2-VL-2B-Instruct", trust_remote_code=True)
23
 
24
+ # Add these new imports and constants
25
+ CLIP_PATH = "google/siglip-so400m-patch14-384"
26
+ VLM_PROMPT = "A descriptive caption for this image:\n"
27
+ MODEL_PATH = "meta-llama/Meta-Llama-3.1-8B"
28
+ CHECKPOINT_PATH = "wpkklhc6"
29
+
30
+ class ImageAdapter(nn.Module):
31
+ def __init__(self, input_features: int, output_features: int):
32
+ super().__init__()
33
+ self.linear1 = nn.Linear(input_features, output_features)
34
+ self.activation = nn.GELU()
35
+ self.linear2 = nn.Linear(output_features, output_features)
36
+
37
+ def forward(self, vision_outputs: torch.Tensor):
38
+ x = self.linear1(vision_outputs)
39
+ x = self.activation(x)
40
+ x = self.linear2(x)
41
+ return x
42
+
43
+ # Load CLIP
44
+ clip_processor = AutoProcessor.from_pretrained(CLIP_PATH)
45
+ clip_model = AutoModel.from_pretrained(CLIP_PATH).vision_model
46
+ clip_model.eval()
47
+ clip_model.requires_grad_(False)
48
+ clip_model.to(device)
49
+
50
+ # Tokenizer
51
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH, use_fast=False)
52
+
53
+ # LLM
54
+ text_model = AutoModelForCausalLM.from_pretrained(MODEL_PATH, device_map="auto", torch_dtype=torch.bfloat16)
55
+ text_model.eval()
56
+
57
+ # Image Adapter
58
+ image_adapter = ImageAdapter(clip_model.config.hidden_size, text_model.config.hidden_size)
59
+ image_adapter.load_state_dict(torch.load(f"{CHECKPOINT_PATH}/image_adapter.pt", map_location="cpu"))
60
+ image_adapter.eval()
61
+ image_adapter.to(device)
62
+
63
  @spaces.GPU
64
  def florence_caption(image):
65
  if not isinstance(image, Image.Image):
 
131
  generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False
132
  )
133
 
134
+ return output_text[0]
135
+
136
+ @spaces.GPU
137
+ @torch.no_grad()
138
+ def joycaption(image):
139
+ if not isinstance(image, Image.Image):
140
+ image = Image.fromarray(np.uint8(image))
141
+
142
+ # Preprocess image
143
+ image = clip_processor(images=image, return_tensors='pt').pixel_values
144
+ image = image.to(device)
145
+
146
+ # Tokenize the prompt
147
+ prompt = tokenizer.encode(VLM_PROMPT, return_tensors='pt', padding=False, truncation=False, add_special_tokens=False)
148
+
149
+ # Embed image
150
+ with torch.amp.autocast_mode.autocast(device_type='cuda', enabled=True):
151
+ vision_outputs = clip_model(pixel_values=image, output_hidden_states=True)
152
+ image_features = vision_outputs.hidden_states[-2]
153
+ embedded_images = image_adapter(image_features)
154
+ embedded_images = embedded_images.to(device)
155
+
156
+ # Embed prompt
157
+ prompt_embeds = text_model.model.embed_tokens(prompt.to(device))
158
+ embedded_bos = text_model.model.embed_tokens(torch.tensor([[tokenizer.bos_token_id]], device=device, dtype=torch.int64))
159
+
160
+ # Construct prompts
161
+ inputs_embeds = torch.cat([
162
+ embedded_bos.expand(embedded_images.shape[0], -1, -1),
163
+ embedded_images.to(dtype=embedded_bos.dtype),
164
+ prompt_embeds.expand(embedded_images.shape[0], -1, -1),
165
+ ], dim=1)
166
+
167
+ input_ids = torch.cat([
168
+ torch.tensor([[tokenizer.bos_token_id]], dtype=torch.long),
169
+ torch.zeros((1, embedded_images.shape[1]), dtype=torch.long),
170
+ prompt,
171
+ ], dim=1).to(device)
172
+ attention_mask = torch.ones_like(input_ids)
173
+
174
+ generate_ids = text_model.generate(input_ids, inputs_embeds=inputs_embeds, attention_mask=attention_mask, max_new_tokens=300, do_sample=True, top_k=10, temperature=0.5, suppress_tokens=None)
175
+
176
+ # Trim off the prompt
177
+ generate_ids = generate_ids[:, input_ids.shape[1]:]
178
+ if generate_ids[0][-1] == tokenizer.eos_token_id:
179
+ generate_ids = generate_ids[:, :-1]
180
+
181
+ caption = tokenizer.batch_decode(generate_ids, skip_special_tokens=False, clean_up_tokenization_spaces=False)[0]
182
+
183
+ return caption.strip()
requirements.txt CHANGED
@@ -10,4 +10,6 @@ git+https://github.com/huggingface/transformers.git
10
  accelerate
11
  qwen-vl-utils
12
  anthropic
13
- groq
 
 
 
10
  accelerate
11
  qwen-vl-utils
12
  anthropic
13
+ groq
14
+ sentencepiece
15
+ huggingface_hub==0.24.3
wpkklhc6/image_adapter.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2ebb1d1437bbb3264a6f25a896b25a7c7dd06c570c5de909dc2f19d3a5c5c110
3
+ size 86018240
wpkklhc6/wpkklhc6_config.yaml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ wandb_project: joy-caption-1
2
+ device_batch_size: 2
3
+ batch_size: 256
4
+ learning_rate: 0.001
5
+ warmup_samples: 18000
6
+ max_samples: 600000
7
+ save_every: 50000
8
+ test_every: 50000
9
+ use_amp: true
10
+ grad_scaler: true
11
+ lr_scheduler_type: cosine
12
+ min_lr_ratio: 0.0
13
+ allow_tf32: true
14
+ seed: 42
15
+ num_workers: 8
16
+ optimizer_type: adamw
17
+ adam_beta1: 0.9
18
+ adam_beta2: 0.999
19
+ adam_eps: 1.0e-08
20
+ adam_weight_decay: 0.0
21
+ clip_grad_norm: 1.0
22
+ dataset: fancyfeast/joy-captioning-20240729a
23
+ clip_model: google/siglip-so400m-patch14-384
24
+ text_model: meta-llama/Meta-Llama-3.1-8B
25
+ resume: null
26
+ gradient_checkpointing: false
27
+ test_size: 2048
28
+ grad_scaler_init: 65536.0
29
+ max_caption_length: 257
30
+ num_image_tokens: 32
31
+ adapter_type: mlp
32
+ text_model_dtype: float16