| | import io |
| | import logging |
| | import json |
| | import torch |
| | import torch.utils.checkpoint |
| | from torch import nn |
| | from torch.nn import MSELoss |
| | from transformers.modeling_outputs import ( |
| | CausalLMOutputWithPast, |
| | ) |
| | from typing import List, Optional, Tuple, Union |
| | from transformers import LlamaForCausalLM |
| | from transformers.modeling_outputs import ( |
| | CausalLMOutputWithPast, |
| | ) |
| |
|
| | from torch.cuda.amp import autocast as autocast |
| | import torch.nn.functional as F |
| |
|
| | import numpy as np |
| | from .modeling_vit import build_vit, MLP, PostProcess |
| |
|
| | from .modeling_qformer import build_qformer |
| | from .modeling_base import BaseMLLM |
| |
|
| | from transformers.modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast |
| | logger = logging.getLogger(__name__) |
| |
|
| | import pycocotools.mask as mask_util |
| |
|
| | from .modeling_base import VID_TOKEN, IMG_TOKEN |
| |
|
| | class MultiModalLLM_PT(BaseMLLM): |
| | def __init__( |
| | self, |
| | config, |
| | _tokenizer=None |
| | ): |
| | super().__init__(config=config, _tokenizer=_tokenizer) |
| | self.use_clip = False |
| | self.num_frames = 16 |
| | self.num_clips = 1 |
| | self.token_merge_len = 4 |
| |
|
| | self.per_clip_frames = self.num_frames // self.num_clips |
| | |
| | print(self.config) |
| | self.merge_proj = nn.Linear( |
| | self.qformer.config.hidden_size*self.token_merge_len, self.config.hidden_size |
| | ) |
| |
|
| | if config.build_decoder: |
| | self.track_embed = MLP(self.config.hidden_size, self.config.hidden_size, 3 * 256, 2, dropout=0) |
| | self.track_embed_decode2 = MLP(4096, 4096, 4, 2, dropout=0) |
| | self.temporal_embed = MLP(self.config.hidden_size, self.config.hidden_size, 2, 2, dropout=0.3) |
| | self.action_embed = MLP(self.config.hidden_size, self.config.hidden_size, 1, 2, dropout=0.3) |
| | self.postprocess = PostProcess() |
| | self.track_token = nn.Parameter(torch.randn((1, 1, 4096))) |
| | self.temporal_token = nn.Parameter(torch.randn((1, 1, 4096))) |
| | self.box_token = nn.Parameter(torch.randn((1, 1, 4096))) |
| |
|
| |
|
| | def forward( |
| | self, |
| | input_ids: torch.LongTensor = None, |
| | attention_mask: Optional[torch.Tensor] = None, |
| | labels: Optional[torch.LongTensor] = None, |
| | image: Optional[torch.Tensor] = None, |
| | video: Optional[torch.Tensor] = None, |
| | instruction = None, |
| | video_idx = None, |
| | image_idx = None, |
| | output_boxes = None, |
| | input_boxes = None, |
| | text_input = None, |
| | video_info = None, |
| | temporal_labels = None, |
| | gt_masks = None, |
| | sam_images = None, |
| | size_hw = None, |
| | path = None, |
| | mask_path = None, |
| | tvg_inputs = None, |
| | tvg_targets = None, |
| | ): |
| | if text_input is not None: |
| | time_instructions = self.get_clip_time_instruct(text_input) |
| | else: |
| | time_instructions = None |
| | text_embeds = self.pad_text_embeds(input_ids=input_ids, image=image, video=video, return_visual=False, |
| | video_idx=video_idx, image_idx=image_idx, instruction = instruction, |
| | output_boxes = output_boxes, input_boxes=input_boxes, time_instructions = time_instructions) |
| | outputs = self.lm( |
| | inputs_embeds=text_embeds, |
| | attention_mask=attention_mask, |
| | labels=labels, |
| | output_hidden_states=True, |
| | return_dict=True, |
| | ) |
| | loss = outputs.loss |
| | logger.info(f'llm loss:{loss}') |
| |
|
| | if output_boxes is not None and self.use_bbox_loss: |
| | last_hidden_states = outputs.hidden_states[-1] |
| | pred_locs = [] |
| | for idx in range(last_hidden_states.shape[0]): |
| | loc_positions = ( (input_ids[idx].flatten() == self.tokenizer.box_token) ).nonzero().flatten() |
| | selected_hidden_states = last_hidden_states[idx][loc_positions] |
| | pred_locs.append(self.loc_decoder(selected_hidden_states)) |
| | box_loss = self.box_loss(pred_locs, output_boxes) |
| | logger.info(f'box loss:{box_loss}') |
| | loss += box_loss |
| | |
| | if (gt_masks is not None or input_boxes is not None) and self.use_mask_loss: |
| | last_hidden_states = outputs.hidden_states[-1] |
| | pred_masks = [] |
| | sam_losses = [] |
| | box_losses = [] |
| | for idx in range(last_hidden_states.shape[0]): |
| | loc_positions = ( (input_ids[idx].flatten() == self.tokenizer.track_token) ).nonzero().flatten() |
| | selected_hidden_states = last_hidden_states[idx][loc_positions] |
| | embed_sam_boxes = self.track_embed(selected_hidden_states).reshape(1, 3, 256) |
| | inference_state = self.sam.init_state_images(sam_images, size_hw[idx][0], size_hw[idx][1]) |
| | |
| | if input_boxes is not None: |
| | gt_embeds = self.sam.get_prompt_embeding(inference_state, None, None, False, input_boxes[idx], device = text_embeds.device) |
| | else: |
| | input_boxes = self.find_boundaries_torch(gt_masks.squeeze(0)[:,:,:1].squeeze(2).cpu()).to(text_embeds.device) |
| | gt_embeds = self.sam.get_prompt_embeding(inference_state, None, None, False, input_boxes, device = text_embeds.device) |
| | pred_locs = [self.track_embed_decode2((selected_hidden_states))[0]] |
| | target_boxes = [input_boxes[idx]] |
| |
|
| | src_boxes = pred_locs |
| | loss_bbox = self.box_loss2(src_boxes, target_boxes) |
| |
|
| | loss_bbox = self.masked_loss(loss_bbox, 0) |
| | box_losses.append(loss_bbox) |
| | sam_losses.append( F.l1_loss(embed_sam_boxes, gt_embeds)) |
| | |
| | logger.info(f'refering sam loss:{sam_losses}') |
| | sam_losses = torch.stack(sam_losses) |
| | box_losses = torch.stack(box_losses) |
| | loss += torch.mean(sam_losses) |
| | loss += torch.mean(box_losses) |
| | |
| | if tvg_inputs is not None and self.use_temporal_loss: |
| | last_hidden_states = outputs.hidden_states[-1] |
| | last_hidden_states = last_hidden_states.view(-1, last_hidden_states.size(-1)) |
| | loc_positions = (input_ids.flatten()==self.tokenizer.temp_token).nonzero().flatten() |
| | prompt_token = last_hidden_states[loc_positions] |
| | prompt_token = prompt_token.view(input_ids.shape[0], -1 ,prompt_token.shape[-1]) |
| |
|
| | |
| | cg_outputs = self.cg_model(**tvg_inputs, targets=tvg_targets, prompt_token=prompt_token) |
| | loss_dict = self.cg_criterion(cg_outputs, tvg_targets) |
| | weight_dict = self.cg_criterion.weight_dict |
| | tvg_loss = 0.05*sum(loss_dict[k] * weight_dict[k] for k in loss_dict.keys() if k in weight_dict) |
| | logger.info(f'tvg_loss:{tvg_loss}') |
| | loss += tvg_loss |
| |
|
| |
|
| | logger.info(f'all loss:{loss}') |
| | return CausalLMOutputWithPast( |
| | loss=loss, |
| | logits=outputs.logits, |
| | past_key_values=outputs.past_key_values, |
| | hidden_states=outputs.hidden_states, |
| | attentions=outputs.attentions, |
| | ) |
| |
|
| | def pad_text_embeds( |
| | self, |
| | input_ids: torch.LongTensor = None, |
| | image: Optional[torch.Tensor] = None, |
| | video: Optional[torch.Tensor] = None, |
| | image_idx = None, |
| | video_idx = None, |
| | return_visual: bool = False, |
| | instruction = None, |
| | output_boxes = None, |
| | input_boxes = None, |
| | time_instructions = None, |
| | ): |
| | text_embeds = self.lm.get_input_embeddings()(input_ids.long()).detach() |
| | if input_boxes is not None: |
| | input_boxes = input_boxes[0].to(dtype=text_embeds.dtype) |
| | |
| | boxes_emb = self.loc_encoder(input_boxes) |
| | boxes_emb = boxes_emb.view(-1, 4096) |
| | |
| | text_embeds[input_ids == torch.full_like(input_ids, self.tokenizer.track_box_token)] = text_embeds[input_ids == torch.full_like(input_ids, self.tokenizer.track_box_token)] * 0 + boxes_emb.to(text_embeds.device) |
| | logger.info(f'embedings:{text_embeds[input_ids == torch.full_like(input_ids, self.tokenizer.track_box_token)].shape}') |
| | visual = None |
| | visual_idx = None |
| | |
| | if image is not None: |
| |
|
| | B, T, C, H, W = image.shape |
| | image = image.permute(0, 2, 1, 3, 4) |
| |
|
| | instruction = None |
| | |
| | prompt_image_embeds = self.encode_vision(image, instruction) |
| |
|
| | visual = prompt_image_embeds |
| |
|
| | prompt_image_embeds = self.project_up(prompt_image_embeds) |
| | prompt_image_embeds = prompt_image_embeds.view(-1, prompt_image_embeds.shape[-1]) |
| |
|
| | visual_idx = image_idx |
| |
|
| | prompt_image_embeds = prompt_image_embeds.to(dtype=text_embeds.dtype) |
| |
|
| | text_embeds[image_idx == 1] = torch.zeros_like(text_embeds[image_idx == 1]) + prompt_image_embeds.to(text_embeds.device) |
| |
|
| |
|
| | elif video is not None: |
| | if len(video.shape) == 5: |
| | B, T, C, H, W = video.shape |
| | N = 1 |
| | if self.use_clip: |
| | video = video.reshape(B*self.num_clips, T//self.num_clips, C, H, W) |
| | else: |
| | B, N, T, C, H, W = video.shape |
| |
|
| | video = video.permute(0,2,1,3,4) |
| |
|
| |
|
| | prompt_video_embeds = self.encode_vision(video, instruction=time_instructions) |
| | if self.use_clip: |
| | prompt_video_embeds = prompt_video_embeds.reshape(B,-1,prompt_video_embeds.shape[-1]) |
| | batch_size, img_len, token_dim = prompt_video_embeds.shape |
| | prompt_video_embeds = prompt_video_embeds.view(batch_size, img_len // self.token_merge_len, self.token_merge_len * token_dim) |
| | prompt_video_embeds = self.merge_proj(prompt_video_embeds) |
| | prompt_video_embeds = prompt_video_embeds.view(-1, prompt_video_embeds.shape[-1]) |
| | |
| | else: |
| | prompt_video_embeds = self.project_up(prompt_video_embeds) |
| |
|
| | prompt_video_embeds = prompt_video_embeds.view(-1, prompt_video_embeds.shape[-1]) |
| | visual_idx = video_idx |
| | |
| | |
| | text_embeds[video_idx == 1] = torch.zeros_like(text_embeds[video_idx == 1]) + prompt_video_embeds.to(text_embeds.device).to(text_embeds.dtype) |
| | |
| | else: |
| | logger.warn(f"don't get visual input, input_ids: {input_ids}") |
| | |
| |
|
| | for idx, text_embed in enumerate(text_embeds): |
| | if text_embeds[idx][input_ids[idx].flatten() == self.tokenizer.box_token].shape[0] != 0: |
| | text_embeds[idx][input_ids[idx].flatten() == self.tokenizer.box_token] = torch.zeros_like(text_embeds[idx][input_ids[idx] == self.tokenizer.box_token]) + torch.cat([self.box_token.squeeze(0)] * (text_embeds[idx][input_ids[idx] == self.tokenizer.box_token]).shape[0]).to(text_embeds.dtype) |
| | if text_embeds[idx][input_ids[idx].flatten() == self.tokenizer.temp_token].shape[0] != 0: |
| | text_embeds[idx][input_ids[idx].flatten() == self.tokenizer.temp_token] = torch.zeros_like(text_embeds[idx][input_ids[idx] == self.tokenizer.temp_token]) + self.temporal_token |
| | if text_embeds[idx][input_ids[idx].flatten() == self.tokenizer.track_token].shape[0] != 0: |
| | text_embeds[idx][input_ids[idx].flatten() == self.tokenizer.track_token] = torch.zeros_like(text_embeds[idx][input_ids[idx] == self.tokenizer.track_token]) + self.track_token |
| | |
| | if return_visual: |
| | return text_embeds, visual, visual_idx |
| | |
| | return text_embeds |
| |
|
| | |
| | |
| | def temporal_decode(self, temporal_embedding): |
| | pred_sted = self.temporal_embed(temporal_embedding) |
| | pred_actioness = self.action_embed(temporal_embedding) |
| | return pred_sted, pred_actioness |
| |
|
| | |
| | def box_loss2(self, src_boxes, target_boxes): |
| | src_boxes = torch.cat(src_boxes) |
| | target_boxes = torch.cat(target_boxes) |
| |
|
| | loss_bbox = F.l1_loss(src_boxes, target_boxes, reduction='none') |
| | loss_bbox = self.masked_loss(loss_bbox, 0) |
| | mask = (src_boxes[2:] >= src_boxes[:2]).all(-1) |
| | src_boxes = src_boxes[mask] |
| | target_boxes = target_boxes[mask] |
| |
|
| | return loss_bbox |
| |
|
| | def box_loss(self, src_boxes, target_boxes): |
| | src_boxes = torch.cat(src_boxes) |
| | target_boxes = torch.cat(target_boxes) |
| |
|
| | loss_bbox = F.l1_loss(src_boxes, target_boxes, reduction='none') |
| | loss_bbox = self.masked_loss(loss_bbox, 0) |
| | mask = (src_boxes[:, 2:] >= src_boxes[ :, :2]).all(-1) |
| | src_boxes = src_boxes[mask] |
| | target_boxes = target_boxes[mask] |
| |
|
| | if src_boxes.shape[0] > 0: |
| | loss_giou = 1 - torch.diag(generalized_box_iou( |
| | src_boxes, |
| | target_boxes)) |
| | loss_giou = self.masked_loss(loss_giou, 0) |
| | else: |
| | loss_giou = torch.tensor(2, dtype=src_boxes.dtype) |
| | iou, union = box_iou(src_boxes, target_boxes) |
| | |
| | return loss_bbox * 2 + loss_giou / 5 |
| | |
| | def find_boundaries_torch(self, mask): |
| |
|
| | from skimage.segmentation import find_boundaries |
| | mask_np = mask.to(torch.bool).numpy() |
| | boundaries = find_boundaries(mask_np, mode='outer') |
| | boundary_points = np.argwhere(boundaries) |
| | if boundary_points.size == 0: |
| | return torch.tensor([-1, -1, -1, -1], dtype = torch.bfloat16) |
| | h0, w0 = boundary_points.min(axis=0) |
| | h1, w1 = boundary_points.max(axis=0) |
| | return torch.tensor([w0 / mask.shape[1], h0 / mask.shape[0], w1 / mask.shape[1], h1 / mask.shape[0]], dtype = torch.bfloat16) |
| |
|
| |
|
| | def sam_loss(self, sam_outputs, gt_masks): |
| | bound1 = self.find_boundaries_torch(gt_masks[:,:,:1].squeeze(2).cpu()) |
| | bound2 = self.find_boundaries_torch(sam_outputs[:,:,:1].squeeze(2).cpu()) |
| |
|
| | lossl1 = F.l1_loss(bound1, bound2, reduction='none') |
| | lossl1 = self.masked_loss(lossl1, 0) |
| |
|
| | loss_iou = self.iou_loss(sam_outputs, gt_masks) |
| | loss_dice = self.dice_loss(sam_outputs, gt_masks) |
| |
|
| | |
| | return loss_iou + loss_dice + lossl1 |
| | |
| | def masked_loss(self, loss, n): |
| | mask = torch.ones_like(loss) |
| | |
| | loss = (loss*mask).sum()/(mask.sum()) |
| | return loss |
| |
|
| | def encode_vision( |
| | self, |
| | image, |
| | instruction |
| | ): |
| | device = image.device |
| | B = image.shape[0] |
| | T = image.shape[2] |
| | use_image = True if T == 1 else False |
| | image_embeds = self.vision_encoder(image, use_image=use_image) |
| | C = image_embeds.shape[-1] |
| | image_embeds = image_embeds.reshape(B, -1, C) |
| | image_embeds = self.vision_layernorm(image_embeds).to(device) |
| | |
| | image_atts = torch.ones(image_embeds.size()[:-1], dtype=torch.long).to(device) |
| | if self.extra_num_query_token > 0: |
| | query_tokens = torch.cat([self.query_tokens, self.extra_query_tokens], dim=1) |
| | query_tokens = query_tokens.expand(image_embeds.shape[0], -1, -1) |
| | if instruction is not None: |
| | text_Qformer = self.qformer_tokenizer( |
| | instruction, |
| | padding='longest', |
| | truncation=True, |
| | max_length=512, |
| | return_tensors="pt", |
| | ).to(image_embeds.device) |
| | query_atts = torch.ones(query_tokens.size()[:-1], dtype=torch.long).to(image_embeds.device) |
| | Qformer_atts = torch.cat([query_atts, text_Qformer.attention_mask], dim=1) |
| | query_output = self.qformer.bert( |
| | text_Qformer.input_ids, |
| | attention_mask=Qformer_atts, |
| | query_embeds=query_tokens, |
| | encoder_hidden_states=image_embeds, |
| | encoder_attention_mask=image_atts, |
| | return_dict=True, |
| | ) |
| | else: |
| | query_output = self.qformer.bert( |
| | query_embeds=query_tokens, |
| | encoder_hidden_states=image_embeds, |
| | encoder_attention_mask=image_atts, |
| | return_dict=True, |
| | ) |
| | |
| | return query_output.last_hidden_state[:, :query_tokens.size(1), :] |
| |
|
| | def generate_caption( |
| | self, |
| | input_ids, |
| | attention_mask, |
| | image_idx = None, |
| | video_idx = None, |
| | image: Optional[torch.Tensor] = None, |
| | video: Optional[torch.Tensor] = None, |
| | num_beams=1, |
| | max_new_tokens=200, |
| | do_sample=True, |
| | top_p=0.9, |
| | top_k=None, |
| | temperature=1.0, |
| | length_penalty=1, |
| | repetition_penalty=1.0, |
| | ): |
| | text_embeds = self.pad_text_embeds(input_ids=input_ids, image=image, video=video, image_idx=image_idx, video_idx=video_idx) |
| | outputs = self.lm.generate( |
| | inputs_embeds=text_embeds, |
| | attention_mask=attention_mask, |
| | num_beams=num_beams, |
| | max_new_tokens=max_new_tokens, |
| | do_sample=do_sample, |
| | min_length=1, |
| | top_p=top_p, |
| | top_k=top_k, |
| | temperature=temperature, |
| | length_penalty=length_penalty, |
| | repetition_penalty=repetition_penalty, |
| | ) |
| |
|
| | return outputs |
| |
|
| | def generate_caption_bbox( |
| | self, |
| | input_ids, |
| | attention_mask, |
| | labels, |
| | image_idx = None, |
| | video_idx = None, |
| | image: Optional[torch.Tensor] = None, |
| | video: Optional[torch.Tensor] = None, |
| | num_beams=1, |
| | max_new_tokens=200, |
| | do_sample=True, |
| | top_p=0.9, |
| | top_k=None, |
| | temperature=0.9, |
| | length_penalty=1, |
| | repetition_penalty=1.0, |
| | ): |
| | text_embeds = self.pad_text_embeds(input_ids=input_ids, image=image, video=video, image_idx=image_idx, video_idx=video_idx) |
| | outputs = self.lm.generate( |
| | inputs_embeds=text_embeds, |
| | attention_mask=attention_mask, |
| | num_beams=num_beams, |
| | max_new_tokens=max_new_tokens, |
| | do_sample=do_sample, |
| | min_length=1, |
| | top_p=top_p, |
| | top_k=top_k, |
| | temperature=temperature, |
| | length_penalty=length_penalty, |
| | repetition_penalty=repetition_penalty, |
| | ) |
| | decoded_text = self.tokenizer.decode(outputs[0], skip_special_tokens=True) |
| | |
| | |
| | return outputs |
| | |
| | def generate_temporal(self, |
| | input_ids: torch.LongTensor = None, |
| | attention_mask: Optional[torch.Tensor] = None, |
| | labels: Optional[torch.LongTensor] = None, |
| | image: Optional[torch.Tensor] = None, |
| | video: Optional[torch.Tensor] = None, |
| | instruction = None, |
| | video_idx = None, |
| | image_idx = None, |
| | boxes = None, |
| | text_input = None, |
| | video_info = None, |
| | temporal_labels = None): |
| |
|
| | if text_input is not None: |
| | time_instructions = self.get_clip_time_instruct(text_input) |
| | else: |
| | time_instructions = None |
| | text_embeds = self.pad_text_embeds(input_ids=input_ids, image=image, video=video, return_visual=False, |
| | video_idx=video_idx, image_idx=image_idx, instruction = instruction, |
| | boxes = boxes, time_instructions = time_instructions) |
| | |
| | |
| | outputs = self.lm( |
| | inputs_embeds=text_embeds, |
| | attention_mask=attention_mask, |
| | labels=labels, |
| | output_hidden_states=True, |
| | return_dict=True, |
| | ) |
| |
|
| | if temporal_labels is not None: |
| | start_sec = temporal_labels["start_sec"] |
| | end_sec = temporal_labels["end_sec"] |
| | fps = video_info['fps'] |
| | frame_indices = video_info['frame_indices'] |
| |
|
| | last_hidden_states = outputs.hidden_states[-1] |
| | last_hidden_states = last_hidden_states.view(-1, last_hidden_states.size(-1)) |
| | loc_positions = (input_ids.flatten()==self.tokenizer.temp_place_ids).nonzero().flatten() |
| | selected_hidden_states = last_hidden_states[loc_positions] |
| | selected_hidden_states = selected_hidden_states.view(input_ids.shape[0], -1 ,selected_hidden_states.shape[-1]) |
| |
|
| | |
| | |
| | |
| |
|
| | pred_sted, pred_actionness = self.temporal_decode(selected_hidden_states) |
| |
|
| | pred_sted = self.postprocess(pred_sted, frame_indices) |
| | pred_sec_s = pred_sted[0][0] / fps[0][0].item() |
| | pred_sec_e = pred_sted[0][1] / fps[0][0].item() |
| |
|
| | output_file = "predictions2.jsonl" |
| | prediction = {"pred_sec_s": round(pred_sec_s, 1), "pred_sec_e": round(pred_sec_e, 1), "start_sec":float(start_sec[0]), "end_sec": float(end_sec[0])} |
| |
|
| | with open(output_file, 'a') as f: |
| | json.dump(prediction, f) |
| | f.write('\n') |
| |
|
| | return outputs |
| |
|
| | def generate_seg(self, input_ids, attention_mask, labels, image, image_idx, video, video_idx, input_boxes, size_hw, sam_images): |
| | device = input_ids.device |
| | prompt = input_ids |
| | l_prompt = len(input_ids) |
| | temperature = 1e-5 |
| | max_new_tokens = 20 |
| | guide_w = 5 |
| | stop_str = '</s>' |
| | bbox = [] |
| | output_ids = list(input_ids[0]) |
| | text_embeds = self.pad_text_embeds(input_ids=input_ids, image=image, video=video, image_idx=image_idx, video_idx=video_idx, return_visual=False, |
| | instruction = None, output_boxes=None, input_boxes=input_boxes) |
| | for i in range(max_new_tokens): |
| | if i == 0: |
| | outputs = self.lm( |
| | inputs_embeds=text_embeds, |
| | attention_mask=attention_mask, |
| | output_hidden_states=True, |
| | return_dict=True, |
| | ) |
| | logits = outputs.logits |
| | past_key_values = outputs.past_key_values |
| | else: |
| | attention_mask = torch.ones(1, past_key_values[0][0].shape[-2] + 1, device=device) |
| | last_text_embeds = self.lm.get_input_embeddings()(torch.tensor(output_ids[-1], device=device).long()).detach().unsqueeze(0) |
| | last_text_embeds = last_text_embeds.unsqueeze(0) |
| | |
| | out = self.lm( |
| | input_ids=None, |
| | use_cache=True, |
| | attention_mask=attention_mask, |
| | output_hidden_states=True, |
| | inputs_embeds=last_text_embeds, |
| | past_key_values=past_key_values, |
| | ) |
| | logits = out.logits |
| | past_key_values = out.past_key_values |
| | if logits is not None: |
| | last_token_logits = logits[0][-1] |
| | if temperature < 1e-4: |
| | token = int(torch.argmax(last_token_logits)) |
| | else: |
| | probs = torch.softmax(last_token_logits / temperature, dim=-1) |
| | token = int(torch.multinomial(probs, num_samples=1)) |
| | output_ids.append(token) |
| | ret = self.tokenizer.decode(token) |
| | if ret == '<box_begin>': |
| | attention_mask = torch.ones(1, past_key_values[0][0].shape[-2] + 1, device=device) |
| | bbox_embeds = self.box_token.bfloat16() |
| | out = self.lm( |
| | inputs_embeds=bbox_embeds, |
| | use_cache=True, |
| | attention_mask=attention_mask, |
| | output_hidden_states=True, |
| | past_key_values=past_key_values |
| | ) |
| | last_hidden_states = out.hidden_states[-1] |
| | selected_hidden_states = last_hidden_states[0][0] |
| | bbox.append(self.loc_decoder(selected_hidden_states)) |
| | last_token_logits = logits[0][-1] |
| | if temperature < 1e-4: |
| | token = int(torch.argmax(last_token_logits)) |
| | else: |
| | probs = torch.softmax(last_token_logits / temperature, dim=-1) |
| | token = int(torch.multinomial(probs, num_samples=1)) |
| | if ret == '<track_begin>': |
| | attention_mask = torch.ones(1, past_key_values[0][0].shape[-2] + 1, device=device) |
| | tracking_embeds = self.track_token |
| | out = self.lm( |
| | inputs_embeds=tracking_embeds, |
| | use_cache=True, |
| | attention_mask=attention_mask, |
| | output_hidden_states=True, |
| | past_key_values=past_key_values |
| | ) |
| | last_hidden_states = out.hidden_states[-1] |
| | selected_hidden_states = last_hidden_states[0][0].to(dtype = torch.bfloat16) |
| | |
| | embed_sam_boxes = self.track_embed(selected_hidden_states).reshape(1, 3, 256) |
| | |
| | inference_state = self.sam.init_state_images(sam_images, size_hw[0][0], size_hw[0][1]) |
| | gt_embeds = self.sam.get_prompt_embeding(inference_state, None, None, False, input_boxes[0].cuda(), device = text_embeds.device) |
| | ann_frame_idx = 0 |
| | ann_obj_id = 0 |
| | box = np.array([0, 0, 0, 0], dtype=np.float32) |
| | _, out_obj_ids, out_mask_logits = self.sam.add_new_box_embeding( |
| | inference_state=inference_state, |
| | frame_idx=ann_frame_idx, |
| | obj_id=ann_obj_id, |
| | box=box, |
| | box_embeding=embed_sam_boxes, |
| | ) |
| | video_segments = {} |
| | for out_frame_idx, out_obj_ids, out_mask_logits in self.sam.propagate_in_video(inference_state): |
| | video_segments[out_frame_idx] = { |
| | out_obj_id: (out_mask_logits[i] > 0.0) |
| | for i, out_obj_id in enumerate(out_obj_ids) |
| | } |
| | video_segments = [video_segments[tt][0] for tt in video_segments] |
| | |
| | |
| |
|
| | if (ret == '</s>'): |
| | break |
| | ret = self.tokenizer.decode(output_ids) |
| | del past_key_values |
| | return ret, bbox, video_segments |
| | |
| | def generate_answer(self, tokenizer, instruction, msg, user_prompt, media_type="video",video_tensor=None, image_tensor=None, answer_prompt=None, chat_history=[],return_history=False, debug=False, generation_config={}): |
| | input_ids, attention_masks, labels = [], [], [] |
| |
|
| | conversation = "" |
| | if instruction: |
| | conversation += instruction |
| | conversation += ( |
| | "[INST]" + " " |
| | ) |
| |
|
| | if media_type == 'image': |
| | conversation +=( "<Image>" + IMG_TOKEN + "</Image>") |
| | else: |
| | conversation += ("<Video>" + VID_TOKEN + "</Video>") |
| |
|
| | conversation += ( msg.rstrip() + "[/INST]") |
| |
|
| | for q,a in chat_history: |
| | conversation += (" [INST] " + q + " [/INST]") |
| | conversation += (a + "</s>") |
| | |
| | conversation += (" [INST] " + user_prompt + " [/INST]") |
| | conversation += ("") |
| | if answer_prompt: |
| | conversation += ("Best Option: (") |
| | total_len = 0 |
| | indexs = [] |
| | if debug: |
| | print(conversation) |
| |
|
| | tokenized = tokenizer.build_input_ids([conversation], |
| | max_length=1024, |
| | add_special_tokens=True, |
| | truncation=False, |
| | padding=False, |
| | return_tensors='pt', |
| | image=image_tensor, |
| | video=video_tensor, |
| | require_video=True) |
| | if video_tensor is not None: |
| | generation_output = self.generate_caption( |
| | tokenized['input_ids'].unsqueeze(0).to(self.device), |
| | tokenized['attention_mask'].unsqueeze(0).to(self.device), |
| | video_idx = tokenized['video_index'].unsqueeze(0), |
| | video = video_tensor.unsqueeze(0).to(self.device,dtype=torch.bfloat16), |
| | do_sample=False |
| | ) |
| | elif image_tensor is not None: |
| | generation_output = self.generate_caption( |
| | tokenized['input_ids'].unsqueeze(0).to(self.device), |
| | tokenized['attention_mask'].unsqueeze(0).to(self.device), |
| | image_idx = tokenized['image_index'].unsqueeze(0), |
| | image = image_tensor.unsqueeze(0).to(self.device,dtype=torch.bfloat16), |
| | do_sample=False |
| | ) |
| | response = tokenizer.batch_decode(generation_output, skip_special_tokens=True)[0] |
| | if debug: |
| | print(response) |
| | return response, chat_history |