Spaces:
Running on Zero
Running on Zero
| """ | |
| Adapted from salesforce@LAVIS. Below is the original copyright: | |
| Copyright (c) 2023, salesforce.com, inc. | |
| All rights reserved. | |
| SPDX-License-Identifier: BSD-3-Clause | |
| For full license text, see the LICENSE_Lavis file in the repo root or https://opensource.org/licenses/BSD-3-Clause | |
| """ | |
| import torch | |
| import torch.nn as nn | |
| import torch.distributed as dist | |
| import torch.nn.functional as F | |
| import my_affectgpt.common.dist_utils as dist_utils | |
| from my_affectgpt.common.dist_utils import download_cached_file | |
| from my_affectgpt.common.utils import is_url | |
| from my_affectgpt.common.logger import MetricLogger | |
| from my_affectgpt.models.base_model import BaseModel | |
| from my_affectgpt.models.Qformer import BertConfig, BertLMHeadModel | |
| from my_affectgpt.models.eva_vit import create_eva_vit_g | |
| from transformers import AutoTokenizer, AutoModel, AutoFeatureExtractor, AutoImageProcessor, Wav2Vec2FeatureExtractor | |
| import config | |
| from my_affectgpt.models.blip2 import Blip2Base, disabled_train | |
| import einops | |
| import cv2 | |
| import numpy as np | |
| from PIL import Image | |
| from my_affectgpt.common.registry import registry | |
| from my_affectgpt.models.ImageBind.models.imagebind_model import ImageBindModel, ModalityType | |
| from my_affectgpt.models.ImageBind.models import imagebind_model | |
| # frames: [(b t) h w c] | |
| def func_VideoReader_to_Image(frames): | |
| outputs = [] | |
| for frame in frames: | |
| pil_image = Image.fromarray(frame.cpu().numpy().astype(np.uint8)) | |
| outputs.append(pil_image) | |
| return outputs | |
| ## 这是 Video-Llama 中默认的视觉编码器 [采用 transformer 后的输入] | |
| class EVA_CLIP_G(Blip2Base): | |
| def __init__(self): | |
| super(EVA_CLIP_G, self).__init__() | |
| # use default parameters | |
| self.use_grad_checkpoint = False | |
| self.vit_precision = "fp16" | |
| self.img_size = 224 | |
| self.drop_path_rate = 0 | |
| self.num_query_token = 32 | |
| print('====== Loading VIT ======') | |
| self.visual_encoder, self.ln_vision = self.init_vision_encoder(config.PATH_TO_VISUAL["EVA_CLIP_G"], | |
| self.img_size, self.drop_path_rate, | |
| self.use_grad_checkpoint, self.vit_precision) | |
| ## freeze the weights | |
| for name, param in self.visual_encoder.named_parameters(): | |
| param.requires_grad = False | |
| self.visual_encoder = self.visual_encoder.eval() | |
| for name, param in self.ln_vision.named_parameters(): | |
| param.requires_grad = False | |
| self.ln_vision = self.ln_vision.eval() | |
| """Overwrite model.train with this function to make sure train/eval mode | |
| does not change anymore.""" | |
| self.visual_encoder.train = disabled_train | |
| self.ln_vision.train = disabled_train | |
| print('====== Loading VIT Q-Former ======') | |
| # 之前encoder的输出是 [32, 1408] | |
| self.Qformer, self.query_tokens = self.init_Qformer(self.num_query_token, self.visual_encoder.num_features) | |
| self.Qformer.cls = None | |
| self.Qformer.bert.embeddings.word_embeddings = None | |
| self.Qformer.bert.embeddings.position_embeddings = None | |
| for layer in self.Qformer.bert.encoder.layer: | |
| layer.output = None | |
| layer.intermediate = None | |
| self.load_from_pretrained(url_or_filename=config.PATH_TO_VISUAL['VIT_QFORMER']) | |
| for name, param in self.Qformer.named_parameters(): | |
| param.requires_grad = False | |
| self.Qformer = self.Qformer.eval() | |
| self.Qformer.train = disabled_train | |
| self.query_tokens.requires_grad = False | |
| self.hidden_size = self.Qformer.config.hidden_size # 最终的输出特征维度 [32, 768] | |
| print('====== All these parameters are fixed during training!! ======') | |
| # image encoding: [b c t h w] => [b t q h] | |
| def forward(self, image, raw_image): | |
| device = image.device | |
| batch_size, _, time_length, _, _ = image.size() | |
| image = einops.rearrange(image, 'b c t h w -> (b t) c h w') | |
| # Image Encoder: | |
| image_embeds = self.ln_vision(self.visual_encoder(image)) # (b, t, c, h, w) -> (b, t, block=257, 1408) | |
| # + Q-Former => 将每张图片从 (block=257, 1408) 压缩到 (32, 768) | |
| image_atts = torch.ones(image_embeds.size()[:-1], dtype=torch.long).to(device) # [(b t), block] | |
| query_tokens = self.query_tokens.expand(image_embeds.shape[0], -1, -1) # [1, 32, 768] -> [(b t), 32, 768] | |
| query_output = self.Qformer.bert( | |
| query_embeds=query_tokens, | |
| encoder_hidden_states=image_embeds, | |
| encoder_attention_mask=image_atts, | |
| return_dict=True, | |
| ) # query_output.last_hidden_state is in [(b t), 32, 768] 将每张图片信息压缩到 [32, 768] | |
| q_hidden_state = query_output.last_hidden_state | |
| # 最后输出格式变成 (b t q h) | |
| frame_hidden_state = einops.rearrange(q_hidden_state, '(b t) q h -> b t q h', b=batch_size, t=time_length) | |
| return frame_hidden_state | |
| ## 删除 ViT 的 Q-Former 的版本 [采用 transformer 后的输入] | |
| class EVA_CLIP_G_NO_QFORMER(Blip2Base): | |
| def __init__(self): | |
| super(EVA_CLIP_G_NO_QFORMER, self).__init__() | |
| # use default parameters | |
| self.use_grad_checkpoint = False | |
| self.vit_precision = "fp16" | |
| self.img_size = 224 | |
| self.drop_path_rate = 0 | |
| self.num_query_token = 32 | |
| print('====== Loading VIT ======') | |
| self.visual_encoder, self.ln_vision = self.init_vision_encoder(config.PATH_TO_VISUAL["EVA_CLIP_G"], | |
| self.img_size, self.drop_path_rate, | |
| self.use_grad_checkpoint, self.vit_precision) | |
| ## freeze the weights | |
| for name, param in self.visual_encoder.named_parameters(): | |
| param.requires_grad = False | |
| self.visual_encoder = self.visual_encoder.eval() | |
| for name, param in self.ln_vision.named_parameters(): | |
| param.requires_grad = False | |
| self.ln_vision = self.ln_vision.eval() | |
| """Overwrite model.train with this function to make sure train/eval mode | |
| does not change anymore.""" | |
| self.visual_encoder.train = disabled_train | |
| self.ln_vision.train = disabled_train | |
| self.hidden_size = self.visual_encoder.num_features # 1408 | |
| print('====== All these parameters are fixed during training!! ======') | |
| # image encoding: [b c t h w] => [b t h] | |
| def forward(self, image, raw_image): | |
| device = image.device | |
| batch_size, _, time_length, _, _ = image.size() | |
| image = einops.rearrange(image, 'b c t h w -> (b t) c h w') | |
| # Image Encoder: | |
| image_embeds = self.ln_vision(self.visual_encoder(image)) # [(b t), c, h, w] -> [(b t), block=257, 1408] | |
| # Compresss | |
| image_embeds = torch.mean(image_embeds, axis=1) # [(b t) h] | |
| image_embeds = einops.rearrange(image_embeds, '(b t) h -> b t h', b=batch_size, t=time_length) | |
| return image_embeds | |
| ## 采用 CLIP_VIT_LARGE 里面的函数进行特征提取 [采用 raw data 输入] | |
| class CLIP_VIT_LARGE(Blip2Base): | |
| def __init__(self): | |
| super(CLIP_VIT_LARGE, self).__init__() | |
| print('====== Loading CLIP_VIT_LARGE ======') | |
| model_dir = config.PATH_TO_VISUAL['CLIP_VIT_LARGE'] | |
| self.model = AutoModel.from_pretrained(model_dir) | |
| self.processor = AutoFeatureExtractor.from_pretrained(model_dir) | |
| ## freeze the weights | |
| for name, param in self.model.named_parameters(): | |
| param.requires_grad = False | |
| self.model = self.model.eval() | |
| self.hidden_size = self.model.config.projection_dim # 768 | |
| print('====== All these parameters are fixed during training!! ======') | |
| # image encoding: [b c t h w] => [b t h] | |
| def forward(self, image, raw_image): | |
| device = raw_image.device | |
| batch_size, _, time_length, _, _ = raw_image.size() | |
| raw_image = einops.rearrange(raw_image, 'b c t h w -> (b t) h w c') | |
| raw_image = func_VideoReader_to_Image(raw_image) | |
| inputs = self.processor(images=raw_image, return_tensors="pt")['pixel_values'] | |
| inputs = inputs.to(device) | |
| embeddings = self.model.get_image_features(inputs) # [(b, t) h] | |
| embeddings = einops.rearrange(embeddings, '(b t) h -> b t h', b=batch_size, t=time_length) | |
| return embeddings | |
| ## 采用 CLIP_VIT_BASE (clip-vit-base-patch16) 进行特征提取 [采用 raw data 输入] | |
| class CLIP_VIT_BASE(Blip2Base): | |
| def __init__(self): | |
| super(CLIP_VIT_BASE, self).__init__() | |
| print('====== Loading CLIP_VIT_BASE ======') | |
| model_dir = config.PATH_TO_VISUAL['CLIP_VIT_BASE'] | |
| self.model = AutoModel.from_pretrained(model_dir) | |
| self.processor = AutoFeatureExtractor.from_pretrained(model_dir) | |
| ## freeze the weights | |
| for name, param in self.model.named_parameters(): | |
| param.requires_grad = False | |
| self.model = self.model.eval() | |
| self.hidden_size = self.model.config.projection_dim # 512 | |
| print('====== All these parameters are fixed during training!! ======') | |
| # image encoding: [b c t h w] => [b t h] | |
| def forward(self, image, raw_image): | |
| device = raw_image.device | |
| batch_size, _, time_length, _, _ = raw_image.size() | |
| raw_image = einops.rearrange(raw_image, 'b c t h w -> (b t) h w c') | |
| raw_image = func_VideoReader_to_Image(raw_image) | |
| inputs = self.processor(images=raw_image, return_tensors="pt")['pixel_values'] | |
| inputs = inputs.to(device) | |
| embeddings = self.model.get_image_features(inputs) # [(b, t) h] | |
| embeddings = einops.rearrange(embeddings, '(b t) h -> b t h', b=batch_size, t=time_length) | |
| return embeddings | |
| ## 采用 DINO2_LARGE 进行特征抽取 [采用 raw data 输入] | |
| class DINO2_LARGE(Blip2Base): | |
| def __init__(self): | |
| super(DINO2_LARGE, self).__init__() | |
| print('====== Loading DINO2_LARGE ======') | |
| model_dir = config.PATH_TO_VISUAL['DINO2_LARGE'] | |
| self.model = AutoModel.from_pretrained(model_dir) | |
| self.processor = AutoImageProcessor.from_pretrained(model_dir) | |
| ## freeze the weights | |
| for name, param in self.model.named_parameters(): | |
| param.requires_grad = False | |
| self.model = self.model.eval() | |
| self.hidden_size = self.model.config.hidden_size # 1024 | |
| print('====== All these parameters are fixed during training!! ======') | |
| # image encoding: [b c t h w] => [b t h] | |
| def forward(self, image, raw_image): | |
| device = raw_image.device | |
| batch_size, _, time_length, _, _ = raw_image.size() | |
| raw_image = einops.rearrange(raw_image, 'b c t h w -> (b t) h w c') | |
| raw_image = func_VideoReader_to_Image(raw_image) | |
| inputs = self.processor(images=raw_image, return_tensors="pt")['pixel_values'] | |
| inputs = inputs.to(device) | |
| embeddings = self.model(inputs, output_hidden_states=True).hidden_states # [(b, t)] * [58, 196 patch + 1 cls, feat=768] | |
| embeddings = torch.stack(embeddings)[-1].mean(dim=1) # 读取最后一层特征, 所有block特征取平均, [(b t), feat=768] | |
| embeddings = einops.rearrange(embeddings, '(b t) h -> b t h', b=batch_size, t=time_length) | |
| return embeddings | |
| ## 采用 SigLIP_SO 进行特征抽取 [采用 raw data 输入] | |
| class SigLIP_SO(Blip2Base): | |
| def __init__(self): | |
| super(SigLIP_SO, self).__init__() | |
| print('====== Loading SigLIP_SO ======') | |
| model_dir = config.PATH_TO_VISUAL['SigLIP_SO'] | |
| self.model = AutoModel.from_pretrained(model_dir) | |
| self.processor = AutoImageProcessor.from_pretrained(model_dir) | |
| ## freeze the weights | |
| for name, param in self.model.named_parameters(): | |
| param.requires_grad = False | |
| self.model = self.model.eval() | |
| self.hidden_size = self.model.config.vision_config.hidden_size # 1152 | |
| print('====== All these parameters are fixed during training!! ======') | |
| # image encoding: [b c t h w] => [b t h] | |
| def forward(self, image, raw_image): | |
| device = raw_image.device | |
| batch_size, _, time_length, _, _ = raw_image.size() | |
| raw_image = einops.rearrange(raw_image, 'b c t h w -> (b t) h w c') | |
| raw_image = func_VideoReader_to_Image(raw_image) | |
| inputs = self.processor(images=raw_image, return_tensors="pt")['pixel_values'] | |
| inputs = inputs.to(device) | |
| embeddings = self.model.vision_model(inputs, output_hidden_states=True).hidden_states # [(b, t)] * [58, 196 patch + 1 cls, feat=768] | |
| embeddings = torch.stack(embeddings)[-1].mean(dim=1) # 读取最后一层特征, 所有block特征取平均, [(b t), feat=768] | |
| embeddings = einops.rearrange(embeddings, '(b t) h -> b t h', b=batch_size, t=time_length) | |
| return embeddings | |
| ## 注册 ImageBind 声学编码器 [采用 transformer 后的输入] | |
| class IMAGEBIND(Blip2Base): | |
| def __init__(self): | |
| super(IMAGEBIND, self).__init__() | |
| print('====== Loading IMAGEBIND ======') | |
| model_dir = config.PATH_TO_AUDIO['IMAGEBIND'] | |
| self.audio_encoder, self.hidden_size = imagebind_model.imagebind_huge() | |
| self.audio_encoder.load_state_dict(torch.load(model_dir, weights_only=True)) | |
| ## freeze the weights | |
| for name, param in self.audio_encoder.named_parameters(): | |
| param.requires_grad = False | |
| self.audio_encoder.eval() | |
| print('====== All these parameters are fixed during training!! ======') | |
| # audio: [b, t, 1, 128, 204] # 存储mel spec | |
| # raw_audio: [b, t, 1, 32000] # 存储采样点 | |
| def forward(self, audio, raw_audio): | |
| device = audio.device | |
| _, embeddings = self.audio_encoder.get_audio_feature(audio, modality_type=ModalityType.AUDIO) | |
| return embeddings | |
| ## 注册 DATA2VEC_BASE 声学编码器 [采用 raw data 输入] | |
| class DATA2VEC_BASE(Blip2Base): | |
| def __init__(self): | |
| super(DATA2VEC_BASE, self).__init__() | |
| print('====== Loading DATA2VEC_BASE ======') | |
| model_dir = config.PATH_TO_AUDIO['DATA2VEC_BASE'] | |
| self.model = AutoModel.from_pretrained(model_dir) | |
| self.feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(model_dir) | |
| ## freeze the weights | |
| for name, param in self.model.named_parameters(): | |
| param.requires_grad = False | |
| self.model.eval() | |
| self.hidden_size = self.model.config.hidden_size | |
| print('====== All these parameters are fixed during training!! ======') | |
| # audio: [b, t, 1, 128, 204] # 存储mel spec | |
| # raw_audio: [b, t, 1, 32000] # 存储采样点 | |
| def forward(self, audio, raw_audio): | |
| device = raw_audio.device | |
| raw_audio = raw_audio[:,:,0,:] # [b, t, s] | |
| batch_size, time_length, _ = raw_audio.size() | |
| raw_audio = einops.rearrange(raw_audio, 'b t s -> (b t) s') | |
| layer_ids = [-4, -3, -2, -1] | |
| input_values = self.feature_extractor(raw_audio, sampling_rate=16000, return_tensors="pt").input_values # [(b t), s] | |
| input_values = input_values.to(device) | |
| hidden_states = self.model(input_values[0], output_hidden_states=True).hidden_states # tuple of ((b t), T, D) | |
| feature = torch.stack(hidden_states)[layer_ids].mean(dim=0) # ((b t), T, D) | |
| feature = feature.mean(dim=1) # ((b t), D) | |
| embeddings = einops.rearrange(feature, '(b t) h -> b t h', b=batch_size, t=time_length) | |
| return embeddings | |
| ## 注册 WAVLM_LARGE 声学编码器 [采用 raw data 输入] | |
| class WAVLM_LARGE(Blip2Base): | |
| def __init__(self): | |
| super(WAVLM_LARGE, self).__init__() | |
| print('====== Loading WAVLM_LARGE ======') | |
| model_dir = config.PATH_TO_AUDIO['WAVLM_LARGE'] | |
| self.model = AutoModel.from_pretrained(model_dir) | |
| self.feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(model_dir) | |
| ## freeze the weights | |
| for name, param in self.model.named_parameters(): | |
| param.requires_grad = False | |
| self.model.eval() | |
| self.hidden_size = self.model.config.hidden_size | |
| print('====== All these parameters are fixed during training!! ======') | |
| # audio: [b, t, 1, 128, 204] # 存储mel spec | |
| # raw_audio: [b, t, 1, 32000] # 存储采样点 | |
| def forward(self, audio, raw_audio): | |
| device = raw_audio.device | |
| raw_audio = raw_audio[:,:,0,:] # [b, t, s] | |
| batch_size, time_length, _ = raw_audio.size() | |
| raw_audio = einops.rearrange(raw_audio, 'b t s -> (b t) s') | |
| layer_ids = [-4, -3, -2, -1] | |
| input_values = self.feature_extractor(raw_audio, sampling_rate=16000, return_tensors="pt").input_values # [(b t), s] | |
| input_values = input_values.to(device) | |
| hidden_states = self.model(input_values[0], output_hidden_states=True).hidden_states # tuple of ((b t), T, D) | |
| feature = torch.stack(hidden_states)[layer_ids].mean(dim=0) # ((b t), T, D) | |
| feature = feature.mean(dim=1) # ((b t), D) | |
| embeddings = einops.rearrange(feature, '(b t) h -> b t h', b=batch_size, t=time_length) | |
| return embeddings | |
| ## 注册 WAVLM_LARGE 声学编码器 [采用 raw data 输入] | |
| class HUBERT_LARGE(Blip2Base): | |
| def __init__(self): | |
| super(HUBERT_LARGE, self).__init__() | |
| print('====== Loading HUBERT_LARGE ======') | |
| model_dir = config.PATH_TO_AUDIO['HUBERT_LARGE'] | |
| self.model = AutoModel.from_pretrained(model_dir) | |
| self.feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(model_dir) | |
| ## freeze the weights | |
| for name, param in self.model.named_parameters(): | |
| param.requires_grad = False | |
| self.model.eval() | |
| self.hidden_size = self.model.config.hidden_size | |
| print('====== All these parameters are fixed during training!! ======') | |
| # audio: [b, t, 1, 128, 204] # 存储mel spec | |
| # raw_audio: [b, t, 1, 32000] # 存储采样点 | |
| def forward(self, audio, raw_audio): | |
| device = raw_audio.device | |
| raw_audio = raw_audio[:,:,0,:] # [b, t, s] | |
| batch_size, time_length, _ = raw_audio.size() | |
| raw_audio = einops.rearrange(raw_audio, 'b t s -> (b t) s') | |
| layer_ids = [-4, -3, -2, -1] | |
| input_values = self.feature_extractor(raw_audio, sampling_rate=16000, return_tensors="pt").input_values # [(b t), s] | |
| input_values = input_values.to(device) | |
| hidden_states = self.model(input_values[0], output_hidden_states=True).hidden_states # tuple of ((b t), T, D) | |
| feature = torch.stack(hidden_states)[layer_ids].mean(dim=0) # ((b t), T, D) | |
| feature = feature.mean(dim=1) # ((b t), D) | |
| embeddings = einops.rearrange(feature, '(b t) h -> b t h', b=batch_size, t=time_length) | |
| return embeddings | |
| ## 注册 HUBERT_BASE 声学编码器 (chinese-hubert-base) [采用 raw data 输入] | |
| class HUBERT_BASE(Blip2Base): | |
| def __init__(self): | |
| super(HUBERT_BASE, self).__init__() | |
| print('====== Loading HUBERT_BASE ======') | |
| model_dir = config.PATH_TO_AUDIO['HUBERT_BASE'] | |
| self.model = AutoModel.from_pretrained(model_dir) | |
| self.feature_extractor = Wav2Vec2FeatureExtractor.from_pretrained(model_dir) ## freeze the weights | |
| for name, param in self.model.named_parameters(): | |
| param.requires_grad = False | |
| self.model.eval() | |
| self.hidden_size = self.model.config.hidden_size # 768 | |
| print('====== All these parameters are fixed during training!! ======') | |
| # audio: [b, t, 1, 128, 204] # 存储mel spec | |
| # raw_audio: [b, t, 1, 32000] # 存储采样点 | |
| def forward(self, audio, raw_audio): | |
| device = raw_audio.device | |
| raw_audio = raw_audio[:,:,0,:] # [b, t, s] | |
| batch_size, time_length, _ = raw_audio.size() | |
| raw_audio = einops.rearrange(raw_audio, 'b t s -> (b t) s') | |
| layer_ids = [-4, -3, -2, -1] | |
| input_values = self.feature_extractor(raw_audio, sampling_rate=16000, return_tensors="pt").input_values # [(b t), s] | |
| input_values = input_values.to(device) | |
| hidden_states = self.model(input_values[0], output_hidden_states=True).hidden_states # tuple of ((b t), T, D) | |
| feature = torch.stack(hidden_states)[layer_ids].mean(dim=0) # ((b t), T, D) | |
| feature = feature.mean(dim=1) # ((b t), D) | |
| embeddings = einops.rearrange(feature, '(b t) h -> b t h', b=batch_size, t=time_length) | |
| return embeddings | |