https://github.com/DAMO-NLP-SG/Video-LLaMA
整个模型,蓝色的blocks都是可以被拿来直接用的,橙色部分是一定要经过训练,以促成Llama video 模型正常联通使用的。
视觉和语音部分都大同小异:
相同点:
不同点:
4. 数据类型和格式
5. 根据数据类型对Qformer结构做了些调整
6. 图像encoder 用的是 Blip-2 中专门做图像语义理解的部分,这个部分的结构:EVA CLIP + Q-former
7. 语音encoder 用的是 Facebook 的 imagebind
模型训练是分段的:
第一阶段 : 粗训(相当于小朋友的兴趣班),用 图像-caption 数据
第二阶段 :精细训(相当于上完兴趣班再上专业集训),用质量高的数据(根据想要的效果来)。比如都是跳舞,但这里可以是专业芭蕾或者专业民族舞,再或者街舞
这个内容在 BLIP-2里。基本上video-lama 就是base在这个模型里改的。
self.video_frame_position_embedding:
nn.Embedding(max_frame_pos, self.Qformer.config.hidden_size)
整个代码里的部件权重加载在 video_llama.py
完成,其中,尽管我们之前下载了那么多权重,但是依然有些权重需要临时下载并加载(一般在.cache
这个folder):
例如:blip2_pretrained_flant5xxl.pth
和语音模型相关的由 LlamaForCausalLM
处理:
Causal LM(CLM):This is the standard left-to-right auto-regressive language model pre-training, used in many standard pre-trained models, like GPT, LLaMA-7B
视觉Encoder: VideoQformer:
self.video_Qformer,self.video_query_tokens = self.init_video_Qformer(num_query_token = num_video_query_token,\
vision_width=self.Qformer.config.hidden_size, num_hidden_layers =2)
num_video_query_token = 32
hidden_size = 768
音频Encoder: Audio former:
ImageBind: video_llama/models/ImageBind/models/imagebind_model.py
self.audio_encoder,self.audio_hidden_size = \
imagebind_model.imagebind_huge()
num_video_query_token = 8
hidden_size = 1024
self.audio_Qformer,self.audio_query_tokens = self.init_video_Qformer(num_query_token = self.num_audio_query_token,\
vision_width=self.audio_hidden_size, num_hidden_layers =2)
video_llama/processors/video_processor.py
视频默认不管什么尺寸,进入Encoder前,都会被resize成224x224, 受限于transfomer attention的套路,等边长的resolution 比如 512x512, 768x768都可以用。在DETR的变种已经妥善处理了各种尺寸输入输出的问题。
不管输入多少秒的视频,目前都是均匀的从视频里抽8 个帧:
indices = np.arange(start, end, vlen / n_frms).astype(int).tolist()
视频处理resize还要经过mean std的normalisation的处理: (1,3,8,224,224)
然后放进encode_videoQformer_visual()
, frame_hidden_state的结果和token接入到bert 得到 llama 相关的embedding,用于后续提问。
output: inputs_llama, atts_llama ===> img_list
问答在:
llm_message = chat.answer(conv=chat_state,
img_list=img_list,
num_beams=num_beams,
temperature=temperature,
max_new_tokens=300,
max_length=2000)[0]
由于这个模型里的视频帧是均匀抽取8个帧,如果只有一秒的视频,那么很容易抽到的8张图都是一样的,那么描述就会像在说车轱辘话一样,来回重复并颠倒。因此,为了符合这个模型的特点,建议先用长一点的视频,再经过快进处理。这样模型可以能更好区分场景变化和理解视频,而不至于被相同的帧误导。
Code 里使用 ‘eva_clip_g’, image size = 224, fp16
Blip2(Blip) 的Q_former 用了pretrain 的 flant.pth
query_output = self.Qformer.bert(
query_embeds=query_tokens,
encoder_hidden_states=image_embeds,
encoder_attention_mask=image_atts,
return_dict=True,
)
这里的 encoder_hidden_states 产自 Clip。query_output (模型前部分输出的内容)是llama 的 input, 即一个包含视频内容理解的embeding.
Clip 在这里的用处和stable diffusion一样,就是用于获取image embedding用的。主要是 Clip 训练数据够多,所以用它得到的image embedding包含的信息会更有意义。
初代BLIP 主要用力在怎么让图片描述更贴合实际情况。训练时的图片质量决定BLIP 最终的质量,前期的数据清洗工作“Dataset Boostrapping” 加入了大量人工,因此这里的图片可能取决于人工的看心情(…就可能有点点的bias, 但因为都是取自COCO数据集,因此data distribution 还不算是个比较罪过的问题,基本和COCO保持队形)。model结构方面,基本是 VIT+BERT,也是Encoder-Decoder的队形,Decoder model主要是生成描述。Decoupling cross-attetion layer 和 self-attention layer (也就是Encoder,Decoder QKV主要处理的那个部件)以及 feed forward layers 的parameters,能够加速训练。对于更加巨大的数据集,作者建议decoupling more parameters.(我反正感觉自己目前职业生涯,不会遇到这个问题. 作者也建议,盲目的随意加入Tasks 而不考虑 Tasks之间是否能够 work在一起,不是一个明智的路子。
为了得到更好的语言描述,动用了LLM怎么办?BLIP2 这里创新了frozen training的方式。之前在BLIP里,Encoder和Decoder一起训练,BLIP2用了Q-former的部件,将两个不需要的训练的模块(图片,文字)链接在一起,这样一来,训练成本会降低(emmmm…4090还是难以hold住Video llama的训练)
https://github.com/OFA-Sys/Chinese-CLIP
causal mask