light-mer / my_affectgpt /models /encoder.py
multimodalart's picture
multimodalart HF Staff
Upload folder using huggingface_hub
41c4e4e verified
Raw
History Blame Contribute Delete
21.2 kB
"""
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 后的输入]
@registry.register_visual_encoder("EVA_CLIP_G")
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 后的输入]
@registry.register_visual_encoder("EVA_CLIP_G_NO_QFORMER")
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 输入]
@registry.register_visual_encoder("CLIP_VIT_LARGE")
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 输入]
@registry.register_visual_encoder("CLIP_VIT_BASE")
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 输入]
@registry.register_visual_encoder("DINO2_LARGE")
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 输入]
@registry.register_visual_encoder("SigLIP_SO")
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 后的输入]
@registry.register_acoustic_encoder("IMAGEBIND")
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 输入]
@registry.register_acoustic_encoder("DATA2VEC_BASE")
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 输入]
@registry.register_acoustic_encoder("WAVLM_LARGE")
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 输入]
@registry.register_acoustic_encoder("HUBERT_LARGE")
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 输入]
@registry.register_acoustic_encoder("HUBERT_BASE")
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