⚠️ Alpha内测版本警告:此为早期内部构建版本,尚不完整且可能存在错误,欢迎大家提Issue反馈问题或建议。
Skip to content

扩展:多模态对齐训练深度细节

在线 Notebook

对应的交互式版本可在 Google Colab 打开,统一使用方式见 第0章说明

所属章节: 第7章:多模态LLM前置阅读: 7.1 视觉-语言对齐7.2 Qwen2.5-VL 架构


概览

7.1 和 7.2 介绍了对比学习对齐和 LLaVA/Qwen2.5-VL 的架构思路。本节补充:对比学习损失的完整数学推导、CLIP 预训练数据的工程细节、投影层设计的原理,以及为什么 InfoNCE 损失比 MSE 更适合对齐任务。


对比学习损失的数学推导

为什么不用 MSE 做图文对齐

最直觉的想法:让图像特征和对应文本特征的 L2 距离最小。问题在于:

MSE 对齐:
  目标:||f_I(x) - f_T(y)||² → 0
  结果:模型学会把所有图像/文本都映射到同一个点
  → 特征空间退化(collapse),所有向量几乎相同

对比学习的关键改进:同时最小化匹配对距离,最大化不匹配对距离

InfoNCE 损失推导

CLIP 使用的 InfoNCE(Information Noise-Contrastive Estimation)损失:

给定一个 batch,大小为 N:

图像特征:I₁, I₂, ..., Iₙ(归一化到单位球面)
文本特征:T₁, T₂, ..., Tₙ(归一化到单位球面)
(Iᵢ, Tᵢ) 是匹配对,(Iᵢ, Tⱼ) (i≠j) 是不匹配对

图像→文本方向的损失:

LIT=1Ni=1Nlogexp(sim(Ii,Ti)/τ)j=1Nexp(sim(Ii,Tj)/τ)

为什么这等价于交叉熵? 分子是正例的相似度,分母是所有 N 个候选的相似度之和。这正是一个 N 分类问题的 softmax cross-entropy——模型需要在 N 个文本中"识别出"与图像匹配的那一个。

完整 CLIP 损失(对称):

LCLIP=12(LIT+LTI)

温度参数 τ 的作用

τ 值效果问题
τ → 0(极小)只关注最近的负样本,梯度集中训练不稳定,梯度爆炸
τ = 0.07(CLIP默认)适中,鼓励清晰分离
τ → ∞(极大)均匀对待所有负样本,梯度分散学习信号弱,收敛慢

τ 的几何直觉: 小 τ 让 softmax 分布更"尖峰",模型需要把正例相似度推得比所有负例高出很多;大 τ 让分布更平坦,负例的惩罚变弱。

Batch Size 的影响

InfoNCE 的一个特性:batch 越大,负样本越多,训练信号越强。CLIP 原始论文用了 batch size = 32768,这是在单机消费级 GPU 上无法复现的。

Batch size 256:  每张图像有 255 个负样本
Batch size 4096:每张图像有 4095 个负样本
Batch size 32768:每张图像有 32767 个负样本(CLIP原版)

替代方案:MoCo 风格的 Memory Bank

用一个动态队列存储最近的 K 个负样本特征(K >> batch size),解耦 batch size 与负样本数量的关系。


CLIP 预训练数据工程

数据来源

CLIP 原版使用 WebImageText(WIT):4 亿个互联网图像-文字对,由 OpenAI 内部爬取,未公开。

社区复现版本(OpenCLIP / LAION):

数据集规模质量过滤说明
LAION-400M4 亿CLIP 相似度 > 0.3早期版本
LAION-2B23 亿CLIP 相似度 + 去重目前最大开源
DataComp-1B12.8 亿多维度质量过滤性价比更高

为什么 CLIP 相似度过滤是自举(bootstrapping)的

初始 CLIP → 过滤数据 → 训练新 CLIP → 过滤更多数据 → ...

用已有 CLIP 模型的余弦相似度过滤训练数据:相似度低于阈值(通常 0.28-0.3)的图文对被丢弃。这意味着数据质量依赖于过滤器本身的质量——一个弱 CLIP 会丢弃一些其实有用的数据。

数据增强对对比学习的影响

CLIP 训练中常用的图像增强(RandomCrop、ColorJitter)需要谨慎:

❌ 不适合:
  文字图像(旋转后文字变形)
  医学图像(颜色有诊断意义)
  文档图像(裁剪可能丢失关键信息)

✅ 适合:
  自然图像(景物、动物、商品)
  Crop + Flip + ColorJitter 有效

投影层设计原理

为什么需要投影层

ViT 编码器输出的视觉特征和 LLM 的文本 embedding 空间维度不同、语义不同

ViT-L 输出:  [batch, num_patches, 1024]
LLM embedding:[batch, seq_len, 4096]

问题:
  1. 维度不同(1024 vs 4096)
  2. 语义空间不同(视觉特征 vs 文本 token 特征)

MLP 投影 vs Q-Former

LLaVA 的简单 MLP 投影:

python
# 将每个 patch 特征投影到 LLM token 空间
projection = nn.Sequential(
    nn.Linear(1024, 4096),  # 维度对齐
    nn.GELU(),
    nn.Linear(4096, 4096),  # 语义对齐
)
# 输出:[batch, num_patches, 4096] = LLM 可直接处理的 visual tokens

为什么两层 MLP 比一层好? 第一层做维度变换,第二层做非线性特征重组。加入 GELU 激活后,网络能学习视觉特征的非线性组合,而不只是线性映射。

BLIP-2 的 Q-Former(查询转换器):

固定的可学习 query tokens [Q₁, Q₂, ..., Q₃₂]
    ↓ Cross-Attention(query 关注 image patches)
提取最关键的 32 个视觉特征

投影到 LLM 空间
方法视觉 token 数参数量信息损失适合场景
MLP(LLaVA)= patch 数(256)通用图像理解
Q-Former(BLIP-2)固定 32中等高(压缩)资源受限,高效推理
无投影(直接拼接)= patch 数实验性,序列过长

Qwen2.5-VL 的改进方向: 使用更强的投影层和位置相关设计,让视觉特征更好地保留空间信息,这对高分辨率和多图像场景尤为重要。


多模态预训练阶段

三阶段训练策略

大多数多模态 LLM 采用分阶段训练,而不是端到端一次训练:

阶段1:特征对齐(冻结 ViT + 冻结 LLM,只训练投影层)
  目的:让投影层学会把视觉特征翻译成 LLM 能理解的表示
  数据:大规模图文对(数百万条)
  时间:相对短(几十小时)

阶段2:视觉指令微调(冻结 ViT,训练投影层 + LLM)
  目的:让模型学会遵循指令理解图像
  数据:视觉指令数据(LLaVA-Instruct 等,数十万条)
  时间:较长(数百小时)

阶段3(可选):全参数微调
  目的:端到端优化,提升整体性能
  数据:混合数据(需要防止灾难性遗忘)
  时间:最长,成本最高

为什么先冻结 ViT

直觉: ViT 在 ImageNet/LAION 上已经学到了很好的视觉特征,贸然微调可能破坏这些特征,而投影层随机初始化的梯度会"污染" ViT。

对比实验结论: 阶段1 冻结 ViT 的收敛速度比全参数快 3-5 倍,且最终性能相近——预训练的视觉编码器特征足够通用,不需要为每个下游任务重新训练。


常见问题

Q: 为什么多模态 LLM 的幻觉比纯文本 LLM 更严重?

A: 两个原因:

  1. 视觉特征经过投影层后仍有信息损失,LLM 会用语言先验"补全"看不清的细节
  2. 多模态训练数据中图文配对的噪声比纯文本数据更多

缓解方法:增加对比度、分辨率;在 prompt 中明确要求"如果不确定请说不确定"。

Q: 同样大小的模型,多模态比纯文本推理慢多少?

A: 主要开销在视觉 token 数量。224×224 图像 patch size=16 时有 196 个 visual tokens;1024×1024 时有 4096 个 tokens。每个 visual token 和文本 token 一样参与 attention 计算——序列长度增加 4096 使推理成本约增加 4-8×(attention 是序列长度的平方)。


返回: 第7章:多模态LLM

本教程采用 CC BY-NC-SA 4.0 许可协议