学习目标 :掌握 VLM 的基础组成与数据流 → 理解 Vision Encoder、Projector、Q-Former 与 LLM 的连接方式 → 掌握视觉语言对齐与多阶段训练 → 理解 LLaVA、BLIP-2 两种代表性架构的设计差异,为后续现代 VLM 架构学习打下基础。→ ???(架构篇将带来更难更多更复杂的核心设计) 难度 : 重要性 : 曾经,它通晓万卷典籍,却不曾真正看见这世间的山河。如今,视觉为眼,语言为魂,二道归一……沉睡已久的天眼,终于睁开了。 CLIP 始终无法做到 “交互式” 的对话,因此有一个简单的思路实现 VLM ,即把 CLIP 提取的图像特征送入到 LLM 中,这就是许多 VLM 架构的基本思路。 最简单的 VLM 考虑自己搭建一个 VLM,首先需要一个提取视觉特征的,我们可以用预训练的 ViT/CLIP 。还需要有一个输出文字的,我们使用预训练好的 LLM。那么现在就有一个问题,ViT 的视觉特征怎么成为 LLM 的输入。 这里就引入了 VLM 中非常重要的 Projector,经典的架构为例: \text{Image} \xrightarrow{\text{Vision Encoder}} \text{Visual Features} \xrightarrow{\text{Projector}} \text{Visual Tokens} \xrightarrow{\text{LLM}} \text{Answer} 从维度上看,Image 维度为 ​ [B, 3, 224, 224] ​, 经过 Vision Encoder 后得到维度为 ​ [B, 196, 768] ​(这里会把 CLS Token 去掉,因为我们要的是图像的特征)。然后问题就是 LLM 和 ViT 的维度是不同的,可能 LLM 的一个 Token 的维度是 4096,那么经过 Embedding 后维度为 ​ [B, N, 4096] 。这时候就需要 Projector ,他的作用就是让 ViT 的维度和 LLM 的维度进行对齐,最简单的实现里面一般就是一个 Linear 层即可,其矩阵满足 W_p\in\mathbb R^{768\times4096} 。 \underbrace{[B,196,768]}_{\text{Vision Encoder}} \xrightarrow{\mathrm{Projector}} \underbrace{[B,196,4096]}_{\text{LLM 输入维度}} 这个矩阵会慢慢经过训练,Projector 会学会将视觉特征映射为 LLM 能够有效利用的表示。 得到 ​ [B, 196, 4096] 后,就可以直接拼接起来,比如常见的一种拼接 : H_{\mathrm{input}} = [H_{\mathrm{instruction}};Z_v;H_{\mathrm{question}}] \in\mathbb R^{B\times(N+196)\times4096} 这样的好处是,视觉特征可以作为 LLM 输入序列中的一部分,直接参与后续 Self-Attention。 但是这个架构仍然留下了几个问题: Projector 究竟应该怎么训练,需要怎么样的训练数据,训练函数…? 图片分辨率非常高时怎么办?会不会显著增加开销? 这些问题由后面具体一个一个架构来缓解。 LLaVA —— 从视觉特征对齐到多模态指令微调 前面我们已经构建了一个最简单的 VLM,通过 Projector 将 Vision Encoder 输出的视觉特征映射到 LLM 的隐藏维度,再与文本 Token 一起送入语言模型。 但是,这里仍然存在一个问题。即使视觉特征与文本 Embedding 具有相同的维度,也不意味着 LLM 能够正确理解这些视觉信息。那么,应该通过什么方式,让原本只具备语言理解和生成能力的 LLM,逐渐学会利用视觉特征完成任务? LLaVA(Large Language and Vision Assistant)给出了一种简单而有效的方案。它通过 视觉特征对齐 和 多模态指令微调 两个阶段,将预训练视觉编码器与语言模型连接起来,使模型能够根据图片和用户指令生成回答。 LLaVA 的完整架构 从整体结构上看,就和刚刚我们搭建的最简单的 VLM 版本差不多,接下来会用 LLaVA 真实的维度进行: \text{CLIP Vision Encoder} + \text{Linear Projector} + \text{Vicuna LLM} 图片维度为 ​ [224, 224] ​ ,经过 ​ 14*14 ​ Patch 后,取不包含 CLS 的特征,维度为 ​ [B, 256, 1024] (隐藏维度为 1024)。而对于论文中 13B 的模型来看, D_{LLM} 的维度是 ​ 5120 ​,所以中间的 Proj. 的矩阵维度是 ​ [1024, 5120] ​ 。最后输入到 LLM 的向量也和上述的拼接过程一致,图片的维度是 ​ [B, 256, 5120] ​, 假设用户输入的问题经过 Embedding 后,维度是 ​ [B, N, 5120] ​,那么按照第二维度拼接起来就是 ​ [图片, 指令] -> [B, (256+N), 5120] 。 所以这里的流程基本上和上面讲的一致,问题还是那个,Projector 究竟应该怎么训练,这里 LLaVA 采用的是两阶段训练方法,先进行 Feature Alignment ,再进行 Visual Instruction Tuning 为什么 LLaVA 采用两阶段训练? 理论上来说,有一种很简单的训练方法,就是直接准备大量图文问答数据,然后把整个模型一起训练。但是我们其实已经有了预训练好的 CLIP 和 LLM,为什么要重新训练呢?重新从头训练不仅训练成本高,还会让训练好的能力发生变化(可能数据如果不多的话,还会退化)。 所以 LLaVA 先采用 Feature Alignment,冻结 Vision Encoder 和 LLM,只训练 Projector,让视觉特征开始成为 LLM 能够利用的输入。再进行 Visual Instruction Tuning,继续冻结 Vision Encoder,同时训练 Projector 和 LLM,让模型进一步学会根据图片执行不同的语言指令。 Feature Alignment 如何训练? 训练数据是 595K 组经过筛选的 CC3M 图文配对数据,这些数据就是 ​ {image, caption} 的格式,利用这些数据构造单轮指令数据,例如: Human: <image> Provide a brief description of this image. // 这里的问题可以从若干种模版里面进行选择 Assistant: A cat sitting on a sofa. 本质上,就是利用已有图文配对构造一个 视觉条件语言生成任务。 Loss 采用经典的 CE Loss。训练时采用 Teacher Forcing。 \mathcal L_{\mathrm{align}} = -\sum_{t=1}^{T} \log P_\theta(y_t\mid I,x,y_{<t}) 为什么还需要第二阶段 Visual Instruction Tuning? 因为模型实际上对指令的遵循能力还是不够,我们需要进一步强化,让模型理解用户指令,判断应当使用哪些视觉信息,以及如何组织回答。 作者使用 GPT-4 辅助生成数据,先把图片的相关信息转化为文字(比如 Caption, 对象 Bounding Box等),再交给 GPT-4 要求其生成不同形式的问答对,例如: 输入信息: Captions: - A red car is parked beside a blue car. - Two vehicles are parked on a street. Objects: - red car: [0.1, 0.2, 0.4, 0.7] - blue car: [0.5, 0.2, 0.9, 0.8] 输出问答对: Question: What is the spatial relationship between the cars? Answer: The red car is to the left of the blue car. ‍ BLIP-2 在 LLaVA 中,我们将全部的 Tokens 送入到 Proj. 和 LLM 中,现在反过来思考,回答一个问题, 我们真的需要用到全部 Tokens 吗? 假设一张图片有大量背景,可能就 2~3 个 Tokens 是猫的,我们想询问里面物体的种类,就几乎没有必要把背景 Tokens 送入到后面的流程。 其次,我们能不能尽量不修改已经预训练好的 Vision Encoder 和 LLM? 随着 LLM 的规模变大,LLaVA 的第二阶段会微调 LLM,这会增加成本。 BLIP-2 整体架构 它并不简单地把全部视觉特征映射到 LLM,而是在 Vision Encoder 和 LLM 之间加入一个 Q-Former(Querying Transformer) ,利用一组可学习 Query,从视觉特征中提取与语言相关的信息。完整架构如下: \text{Image} \xrightarrow{\text{Frozen ViT}} \text{Visual Features} \xrightarrow{\text{Q-Former}} \text{Query Features} \xrightarrow{\text{Linear}} \text{Visual Prefix} \xrightarrow{\text{Frozen LLM}} \text{Answer} 同样,得到的 Visual Features 可以认为是 ​ [B, 257, 1024] (这里用 ViT 没有用 Transformer 块中最后一层的输出,而是倒数第二层,这其实说明并不一定最后的特征最好,可能根据不同的任务需要配置不同的 layer) 经过 Q-Former 后变成 ​ [B, 32, 768] ,即 Q-Former 接收视觉特征,并最终输出 32 个向量。具体架构我们后面会讲,这里也是核心,很多面试会考。 接下来,经过 Linear Projector,将 Q-Former 的输出映射到 LLM 的隐藏维度,然后和 Prompt 一起送入到 LLM,维度就和之前的类似 ​ [B, (32+N), 2560] ​,其中 ​ 2560 就是 LLM 的隐藏维度。 经过上面的整体流程,我们知道 Q-Former 的作用就是接受全部的视觉特征,转化为 32 个向量,那么他的具体结果就是利用 32 个可以学习的 Query ,从完整的视觉特征中提取知识。这里就出现了两个问题: 1. Query 怎么学习,他咋知道要提取什么信息? 2. 提取出来的信息怎么被 LLM 理解(这个问题其实和 LLaVA 的 proj. 的问题一样了) 因此 BLIP-2 采用两阶段训练,第一阶段利用图文数据训练 Q-Former, 让它学习提取与文本相关的视觉表示。 第二阶段再将 Q-Former 连接到冻结的 LLM,通过视觉条件文本生成任务,让它学会提供 LLM 能够使用的视觉信息。 \underbrace{\text{视觉语言表征学习}}_{\text{Stage 1}} \quad\longrightarrow\quad \underbrace{\text{视觉条件语言生成学习}}_{\text{Stage 2}} Q-Former 是什么?内部架构与计算流程 如图,就是一个改造的 Transformer,有两个共享参数的 Transformer,分别接受 Image 和 Text。 Image Transformer 接收 32 个可学习 Query,通过 Self-Attention 和 Cross-Attention,从 Vision Encoder 的输出中提取视觉信息。 Text Transformer 接收文本 Token,通过 Self-Attention 和 FFN 处理文本,在第一阶段预训练时与 Image Transformer 协同学习视觉语言表示。 这两个 Transformer 之间的 Self-Attention 会进行共享参数,而且还会有不同的 Mask 机制控制交换的信息。 Image Transformer 这里的重点是Cross-Atteniton,这里的 ​ Q ​ 来自于我们需要学习的 Query,而 ​ K, V 来自于 Image Features,那么 Query 就可以自行查询到想要"注意"的东西(当然这个和损失函数的设计有关)。经过学习之后,可能一个 Query 对猫所在的区域权重高,另一个对狗所在的高,这样不同的 Query 就可以提取不同的表示。那么很显然,增大 Query 和计算量肯定要做一个 trade-off 了。 Text Transformer 这里基本上就是标准流程,Text 经过 Tokenizer 和 Embedding,然后 Self-Attention,FFN。 文本 Token 不需要直接与 Vision Encoder 的 257 个视觉 Token 执行 Cross-Attention,而是可以通过 Query 表示间接获得视觉信息。这个 Transformer 只会在一阶段训练的时候有用,到二阶段训练和推理的时候就不使用他了。后面会和具体的 Mask 和训练流程一起讲解流程。 Q-Former 的 Mask 机制和训练流程 前面提到,BLIP-2 采用二阶段训练,第一阶段利用图文数据训练 Q-Former, 让它学习提取与文本相关的视觉表示。 第二阶段再将 Q-Former 连接到冻结的 LLM,通过视觉条件文本生成任务,让它学会提供 LLM 能够使用的视觉信息。 一阶段训练 \text{Image + Text} \rightarrow \text{Frozen Vision Encoder + Q-


  • 情报分类:工作与职业机会
  • 分类依据:内容涉及招聘、求职或职业发展
  • 信息来源:服务器 / LINUX DO - 最新话题
  • 发布时间:2026/10/16 16:55:24