@@ -4,7 +4,7 @@ category:
4
4
- MMLLM
5
5
tag :
6
6
- 多模态
7
- - 编辑中
7
+ - 已发布
8
8
footer : 技术共建,知识共享
9
9
date : 2025-05-25
10
10
cover : assets/cover/BLIP2.png
@@ -675,5 +675,77 @@ Stage 2 是为了把 Q-Former 和冻结参数的 LLM 连接起来,以利用 LL
675
675
676
676
3 . 后将投影后的 $Z$ 添加到 input text embeddings前面,Queries 的输出蕴含了视觉信息,送入LLM时,充当了soft visual prompts 。
677
677
678
- 4 . 由于 Q-Former 已经过预训练以提取语言信息视觉表示,因此它有效地充当信息瓶颈,将最有用的信息提供给 LLM,同时删除不相关的视觉信息。这减少了LLM学习视觉语言对齐的负担,从而缓解了灾难性的遗忘问题。
678
+ > 由于 Q-Former 已经过预训练以提取语言信息视觉表示,因此它有效地充当信息瓶颈,将最有用的信息提供给 LLM,同时删除不相关的视觉信息。这减少了LLM学习视觉语言对齐的负担,从而缓解了灾难性的遗忘问题。
679
+
680
+
681
+ Blip2Qformer 的generate方法负责完成图像描述生成(图文到文本):
682
+
683
+ ``` python
684
+ class Blip2Qformer (Blip2Base ):
685
+ ...
686
+ def generate (
687
+ self ,
688
+ samples , # 输入样本,包含图像和可选文本
689
+ use_nucleus_sampling = False , # 是否使用核采样(top-p采样)
690
+ num_beams = 3 , # beam search的beam数量
691
+ max_length = 30 , # 生成文本的最大长度
692
+ min_length = 10 , # 生成文本的最小长度
693
+ top_p = 0.9 , # 核采样的概率阈值
694
+ repetition_penalty = 1.0 , # 重复惩罚系数
695
+ ):
696
+ # 1. 图像编码阶段
697
+ image = samples[" image" ]
698
+ # 通过视觉编码器(如ViT)提取图像特征 (B, 257, D)
699
+ image_embeds = self .ln_vision(self .visual_encoder(image))
700
+
701
+ # 2. 处理beam search扩展
702
+ if not use_nucleus_sampling:
703
+ # 如果是beam search,需要复制图像特征以匹配beam数量
704
+ # (B, 257, D) -> (B*num_beams, 257, D)
705
+ image_embeds = image_embeds.repeat_interleave(num_beams, dim = 0 )
706
+ else :
707
+ # 核采样时不扩展beam
708
+ num_beams = 1
709
+
710
+ # 创建图像注意力掩码(全1,表示所有图像token有效)
711
+ image_atts = torch.ones(image_embeds.size()[:- 1 ], dtype = torch.long).to(
712
+ image.device
713
+ )
714
+
715
+ # 3. 准备生成参数
716
+ model_kwargs = {
717
+ " encoder_hidden_states" : image_embeds, # 图像特征作为cross-attention的输入
718
+ " encoder_attention_mask" : image_atts, # 图像注意力掩码
719
+ }
720
+
721
+ # 4. 初始化文本输入(以BOS token开头)
722
+ # 形状: (batch_size, 1),初始为[BOS]
723
+ input_ids = (
724
+ torch.LongTensor(image.size(0 ), 1 )
725
+ .fill_(self .tokenizer.bos_token_id)
726
+ .to(image.device)
727
+ )
728
+
729
+ # 5. 扩展可学习的query tokens
730
+ # query_tokens形状: (batch_size, num_query_tokens, D)
731
+ query_tokens = self .query_tokens.expand(image_embeds.shape[0 ], - 1 , - 1 )
732
+
733
+ # 6. 调用Q-Former的生成方法
734
+ outputs = self .Qformer.generate(
735
+ input_ids = input_ids, # 初始文本token [BOS]
736
+ query_embeds = query_tokens, # 可学习query tokens
737
+ max_length = max_length, # 最大生成长度
738
+ min_length = min_length, # 最小生成长度
739
+ num_beams = num_beams, # beam数量
740
+ do_sample = use_nucleus_sampling, # 是否采样
741
+ top_p = top_p, # 核采样参数
742
+ eos_token_id = self .tokenizer.sep_token_id, # 结束符
743
+ pad_token_id = self .tokenizer.pad_token_id, # 填充符
744
+ ** model_kwargs # 图像特征和掩码
745
+ )
746
+
747
+ # 7. 解码生成的token id为文本
748
+ captions = self .tokenizer.batch_decode(outputs, skip_special_tokens = True )
749
+ return captions
750
+ ```
679
751
0 commit comments