File size: 1,609 Bytes
c6b1b88 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | # models/vlm · 视觉多模态 (VLM)
`VLM` 继承自 `LMForCausalLM`,复用 `LM` 主干,只在 `forward` 里把**视觉特征投影后拼到文本 embedding 序列**对应位置。
## 结构
```
VLM(LMForCausalLM)
├─ model: LM # 复用主干
├─ vision_encoder: SiglipVisionEncoder
└─ vision_proj: MMVisionProjector # 图像特征 → LLM hidden
```
## 视觉注入方式(面试重点)
- 文本序列里用特殊 token(如 `<|image_pad|>` × `image_token_len`)占位。
- 图像经 `vision_encoder`(SigLIP) 得到 patch 特征 → `vision_proj` 映射到 `hidden_size` 与目标 token 数。
- `forward` 把投影后的图像特征**替换**掉占位 token 位置的 embedding,再走标准 `LM` 主干。
- 因此 LLM 看到的「图像」就是一段连续的视觉 token,与文本 token 一视同仁。
## 关键字段(`VLMConfig`)
| 字段 | 含义 |
| --- | --- |
| `image_special_token` | 图像占位符,如 `<|image_pad|>` |
| `image_ids` | 占位 token 的 id(如 `[12]`) |
| `image_hidden_size` | 视觉编码器输出维度 |
| `image_token_len` | 单张图压缩成的视觉 token 数 |
## 要点(面试)
- **为什么投影 + 占位而不是 concat 新模态?** 复用现成 LLM 的词嵌入位置,训练稳定,且位置编码天然连续。
- **冻结策略**:训练时常冻结 `vision_encoder`,只训练 `vision_proj` 与 LLM 部分(`freeze_llm` 参数控制),避免灾难性遗忘。
- 视觉 token 数与图像分辨率/分块数解耦,由 `vision_proj` 重采样到固定 `image_token_len`。
|