Skip to content

Commit 667c915

Browse files
authored
Merge pull request #14 from BinaryOracle/master
Master
2 parents c54408e + 974a2ab commit 667c915

File tree

1 file changed

+74
-2
lines changed

1 file changed

+74
-2
lines changed

src/MMLLM/庖丁解牛BLIP2.md

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ category:
44
- MMLLM
55
tag:
66
- 多模态
7-
- 编辑中
7+
- 已发布
88
footer: 技术共建,知识共享
99
date: 2025-05-25
1010
cover: assets/cover/BLIP2.png
@@ -675,5 +675,77 @@ Stage 2 是为了把 Q-Former 和冻结参数的 LLM 连接起来,以利用 LL
675675

676676
3. 后将投影后的 $Z$ 添加到 input text embeddings前面,Queries 的输出蕴含了视觉信息,送入LLM时,充当了soft visual prompts 。
677677

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+
```
679751

0 commit comments

Comments
 (0)