第4章第二阶段:多模态大模型

第4章:多模态大语言模型 (LLaVA)

从零实现 Mini-LLaVA,掌握 Vision Encoder + Projector + LLM 架构,两阶段训练(特征对齐 + 指令微调)。

LLaVAVision-Language 连接器两阶段训练多图推理高分辨率处理

让 LLM 具备"视觉"能力


第一部分:为什么需要多模态 LLM?

1.1 从 CLIP 到 LLaVA — 从"对齐"到"理解"

第3章的 CLIP 解决了视觉-语言对齐问题——它能判断图像与文本是否匹配。但它不能"对话":你不能问它"图像里发生了什么?接下来该怎么办?"

LLaVA (Liu et al., 2023) 解决了这个问题:将 CLIP 的视觉编码器与大语言模型连接起来,使 LLM 能够"看见"并"讨论"图像。

1.2 对自动驾驶的意义

对于 VLA 自动驾驶,多模态 LLM 是核心能力:

- 场景理解:用自然语言描述和推理驾驶场景

- 指令理解:将"在前方路口右转"联系到实际视觉场景

- 决策解释:理解模型为什么会做出某个驾驶决策

- VLA 基础:DriveVLM 等驾驶 VLA 就是 LLaVA + 行动输出

1.3 在 VLA 学习路线中的位置


第1-2章: Transformer + ViT(组件)
第3章:   CLIP(视觉-语言对齐)
第4章:   LLaVA(多模态对话)← 当前
第5章:   多模态推理(Grounding, CoT)
第14章:  VLA(视觉→语言→行动)

第二部分:LLaVA 架构

2.1 三组件架构


┌─────────────────────────────────────────────────────┐
│                     LLaVA 架构                       │
│                                                      │
│  图像 (336×336)         文本 "What do you see?"       │
│       │                       │                      │
│  CLIP ViT-L/14          Tokenizer                    │
│  (Vision Encoder)           │                        │
│       │                       │                      │
│  Patch Features          Text Tokens                 │
│  (576 × 1024)            (T,)                        │
│       │                       │                      │
│  MLP Projector               │                        │
│  (2-layer GELU)              │                        │
│       │                       │                      │
│  Visual Tokens         Text Embeddings               │
│  (576 × 4096)          (T × 4096)                    │
│       │                       │                      │
│       └───────┬───────────────┘                      │
│               │                                      │
│       [Visual | Text] Concatenation                  │
│       (576 + T) × 4096                               │
│               │                                      │
│       Causal LLM (LLaMA/Vicuna)                      │
│               │                                      │
│       Generated Response                             │
│                                                      │
└─────────────────────────────────────────────────────┘

三个核心组件:

1. Vision Encoder:CLIP ViT(预训练,冻结)

2. Projector:MLP/Q-Former,将视觉特征映射到 LLM 空间

3. LLM:Causal Language Model(预训练,Stage 2 解冻)

2.2 Vision Encoder

LLaVA 使用 CLIP 的视觉编码器作为"视觉 Frontend":

- 通常是 ViT-L/14(Large,patch=14)

- 输入 336×336 → 24×24 + CLS = 577 tokens

- 输出 577 × 1024 特征向量(保留空间结构)

关键设计选择:

- 使用 patch features(不用 [CLS] token):保留空间信息

- 使用倒数第二层特征(penultimate layer):比最后一层特征更具语义性

- 视觉编码器保持冻结:预训练的对齐能力已经足够

2.3 Projector(连接器)

Projector 是视觉和语言之间的"翻译器"。三种主流方案:

方案 架构 输出 tokens 参数 使用场景
MLP (LLaVA v1.5) 2层 Linear+GELU 576 ~0.1B 标准方案
Q-Former (BLIP-2) N个可学习 query + Cross-Attn 32-64 ~0.2B token 压缩
C-Abstractor 卷积下采样 + 抽象 144 ~0.05B 效率优化

MLP 为什么有效?

- 简单反而好:2 层 MLP 就能学好跨模态映射

- 不需要压缩 token:LLM 有能力处理 576 个额外的"视觉词"

- 保留完整的空间信息:每个视觉 token 对应图像的一个区域

2.4 LLM

LLaVA 使用预训练的 LLM 作为"语言后端":

- LLaVA v1.5 使用 Vicuna-7B/13B(LLaMA 微调版)

- 4096 维隐藏层

- 因果自注意力

关键 insight:LLM 将 visual tokens 视为一种"外语"——projector 学会了将视觉特征"翻译"为 LLM 能理解的表示。


第三部分:对话格式与 Tokenization

3.1 LLaVA 对话模板


USER: <image>\nWhat do you see in this image?
ASSISTANT: I see a busy city intersection with traffic lights
and several pedestrians crossing the street.</s>
USER: What should a driver be aware of?
ASSISTANT: The driver should pay attention to:
1. Traffic light status (currently green)
2. Pedestrians on the crosswalk
3. Vehicles in adjacent lanes
4. Turn signals from other cars</s>

关键设计:

- <image> token 是视觉占位符,被替换为 visual tokens

- USER:ASSISTANT: 明确对话角色

- </s> 是 EOS token,表示回复结束

- 训练时只对 ASSISTANT 部分计算 loss

3.2 Visual Token 替换


原始序列:
"<image>\nUSER: What do you see?"

Tokenize 后:
[<image>, USER, :, What, do, you, see, ?]

替换 <image>:
[visual_1, visual_2, ..., visual_576, USER, :, What, do, you, see, ?]

最终嵌入:
[V1, V2, ..., V576, T1, T2, T3, T4, T5, T6, T7]  共 576+7 个 tokens

3.3 Loss Masking

只对 ASSISTANT 的回复部分计算 loss:


Position: 0...............50, 51, 52, 53, 54, 55
Content:  [Visual Tokens | USER... | ASSISTANT: ...]
Labels:   [-100, -100, ... -100,  51,  52,  53,  54]
                        ↑              ↑
                prompt不计算loss     只计算assistant部分

labels = input_ids.clone()
# 找到 assistant 开始位置
assistant_start = prompt.index("ASSISTANT:")
labels[:, :assistant_start] = -100  # 不计算 loss

第四部分:两阶段训练

4.1 为什么需要两阶段?

LLaVA 的训练不是简单的端到端——需要分两个阶段:

直觉理解

- Stage 1 让 projector 学会"翻译"视觉特征

- Stage 2 让 LLM 学会"利用"视觉信息进行对话

- 如果直接做 Stage 2,projector 的梯度会与 LLM 的梯度冲突

4.2 Stage 1: 特征对齐 (Feature Alignment)

设置
目标 让 visual tokens 对 LLM 来说"可理解"
可训练 仅 Projector
冻结 Vision Encoder + LLM
数据 图像-描述对(简单)
Batch 256 (大)
学习率 2e-3 (大,因为只训一个小模块)
步数 ~5000 steps

数据格式很简单:


USER: <image>\nDescribe this image in detail.
ASSISTANT: A highway scene with three lanes, clear weather...

这个阶段相当于让 projector 学会"对齐"——将视觉特征翻译为 LLM 能理解的"语言"。

4.3 Stage 2: 指令微调 (Instruction Tuning)

设置
目标 让模型学会多模态对话
可训练 Projector + LLM
冻结 Vision Encoder
数据 多模态多轮对话
Batch 128
学习率 2e-5 (LLM) / 1e-4 (Projector)
步数 ~10000 steps

数据格式更丰富(多轮对话):


USER: <image>\nWhat's the weather condition?
ASSISTANT: It's raining heavily, visibility is reduced.
USER: How should the driver adjust?
ASSISTANT: The driver should: 1) Reduce speed 2) Turn on headlights
3) Increase following distance 4) Be extra cautious of pedestrians

4.4 分组学习率

Stage 2 中,projector 和 LLM 需要不同的学习率:


optimizer = AdamW([
    {"params": projector_params, "lr": 1e-4},   # 较大
    {"params": llm_params, "lr": 2e-5},          # 较小(微调预训练模型)
])

原因:projector 是随机初始化的,需要大步长学习;LLM 已经预训练过,只需小步长微调。

4.5 LoRA 选项

在 Stage 2,可以用 LoRA 替代全量微调:


if use_lora:
    # 冻结 LLM,注入 LoRA adapter
    inject_lora(llm, r=64, alpha=128)
    # 只训练 LoRA 参数 + projector

- 参数效率:只训练 ~1% 的 LLM 参数

- 避免灾难性遗忘

- 方便切换多个下游任务


第五部分:高级技术

5.1 多图像处理

自动驾驶常有多个相机输入。LLaVA-NeXT 支持多图像:


前相机 ─→ Vision Encoder ─→ 576 tokens
后相机 ─→ Vision Encoder ─→ 576 tokens
左相机 ─→ Vision Encoder ─→ 576 tokens
右相机 ─→ Vision Encoder ─→ 576 tokens
                                   ↓
                          [2304 visual tokens | text]
                                   ↓
                                  LLM

策略:

1. 独立编码:每张图独立过 vision encoder

2. 直接拼接:所有 visual tokens 放入序列

3. 分隔标记:用特殊 token 分隔不同图像

5.2 AnyRes — 高分辨率处理

标准 CLIP 输入是 336×336,对于驾驶场景来说太小了(需要看清远处的交通标志)。

LLaVA v1.6 的 AnyRes 策略:


720×960 的高分辨率驾驶图像
         │
    选择最佳分辨率: 672×672(2×2网格)
         │
    分割: 4个 336×336 子图 + 1个缩略图
         │
    编码: 5×577 visual tokens = 2885 tokens
         │
    拼接并送入 LLM

效果:

- 能辨认远处的小目标(交通标志、行人)

- 保留全局场景理解(通过缩略图)

- 代价是更多的 visual tokens

5.3 视觉 Token 压缩

576 个 visual tokens 对于长对话或长视频来说太多了。压缩策略:

- Q-Former:用 32-64 个可学习 query 压缩 → 10x 压缩

- Token Merge (ToMe):合并相似的 adjacent tokens

- C-Abstractor:卷积下采样 → 4x 压缩

- Adaptive Pooling:简单的空间池化


第六部分:驾驶场景应用

6.1 驾驶场景理解


USER: <image>\nDescribe this driving scene in detail.
ASSISTANT: I observe an urban intersection under clear weather:
- Road: 4-lane bidirectional with left-turn lane
- Traffic light: Red for our direction
- Vehicles: 3 cars stopped ahead of us
- Pedestrians: 1 person waiting at crosswalk on the right
- Road markings: Clear lane markings visible
- Signs: Speed limit 40 km/h sign on the right

6.2 驾驶决策推理


USER: <image>\nThe light just turned green. What should I do?
ASSISTANT: Even though the light is green, check:
1. Are pedestrians still crossing? (look at crosswalk)
2. Is the car ahead starting to move?
3. Are there vehicles running the red light from cross street?
After confirming safety, proceed slowly through the intersection.

6.3 危险场景分析


USER: <image>\nIs this a dangerous situation?
ASSISTANT: Yes, this appears hazardous:
1. The vehicle in the adjacent lane is drifting out of its lane
2. Wet road surface (recent rain) — reduced friction
3. The pedestrian on the sidewalk is looking at their phone

Recommendations:
- Increase distance from the drifting vehicle
- Reduce speed for wet conditions
- Be prepared to brake if pedestrian steps onto road

总结

本章建立的核心能力:

1. ✅ LLaVA 三组件架构:Vision Encoder + Projector + LLM

2. ✅ 连接器对比:MLP vs Q-Former vs C-Abstractor

3. ✅ 两阶段训练:特征对齐 + 指令微调

4. ✅ 对话格式化:Loss Masking 只对 assistant 部分计算

5. ✅ 多图像处理:多相机拼接策略

6. ✅ AnyRes 高分辨率:分割→多 patches 编码

7. ✅ 驾驶场景应用:场景描述、决策推理、危险分析


下一章:多模态理解与推理 — 视觉定位、多模态思维链、多模态 Agent