Skip to content
Published on

多模态 AI 的训练方法 — 把多种感觉揉进一个模型

分享
Authors

引言:为什么是多模态

人不会只用单一感觉去认识世界。看照片时会读说明文字,看影像时会听声音。同一个概念,有时以图像的形式进入,有时以文字的形式进入,但在我们脑中最终会汇成同一份意义。多模态 AI(multimodal AI)正是想在模型内部实现这种汇合。

传统的深度学习模型只处理一种模态。图像分类器只吃图像,语言模型只吃文本。但现实中的问题往往跨越模态边界。「这张照片里正在发生什么?」这样的问题,只有同时理解图像和文本才能回答。从文档理解、视频检索、语音助手到机器人,越来越多的任务离开多模态就解不了。

本文讨论如何把多种感觉(模态)整合进一个模型。核心在于把不同的模态对齐(alignment)到同一个语义空间,再把这些表示有效地融合(fusion)。我们会从以 CLIP 为代表的对比学习(contrastive learning)讲起,依次涉及预训练与微调、数据的规模与质量、评估方法,以及幻觉之类的局限。

多模态到底在处理什么

先明确模态是什么。模态(modality)指的是数据进入模型的感觉通道或形式。常见的有:

  • 图像:像素网格,具有空间结构。
  • 文本:token 的序列,离散且有顺序。
  • 音频:随时间变化的波形或频谱图,连续,时间轴是关键。
  • 视频:图像帧的序列,往往还带音频,空间与时间在此结合。

多模态模型在输入或输出上处理两种以上的模态。同时接收图像与文本并给出答案的视觉-语言模型(VLM)、用文本生成图像的模型、把音频转成文本的模型,都属于多模态的范畴。

不同模态的统计性质差异很大。图像是连续、高维、局部相关性强的;文本是离散的,长程依赖很强。处理这种异质性正是多模态学习的出发点。

各模态的表示形式(概念)

图像 : 图块网格   -> 图块嵌入序列
文本 : token 序列 -> token 嵌入序列
音频 : 频谱图     -> 帧嵌入序列
视频 : 帧集合     -> 时空嵌入序列

核心:一切最终都变成"嵌入向量的序列",
     再送入共同的处理骨干网络(如 Transformer)。

核心原理:把模态对齐到同一空间

多模态学习最根本的想法,是把不同的模态映射到同一个共享嵌入空间(shared embedding space)。训练的目标是让含义相同的图像和文本在这个空间里彼此靠近。

什么是共享嵌入空间

每种模态都有专属的编码器。图像编码器把图像转成向量,文本编码器把句子转成向量。当两个编码器的输出落在同一维度的空间里,且语义上对应的一对彼此靠近时,模型就获得了跨模态比较的能力。

共享嵌入空间(概念图)

  图像编码器 ──> z_image  ─┐
                          ├─> 同维度 D 的向量空间
  文本编码器 ──> z_text   ─┘

  目标:配对正确的(图像, 文本)靠近,
        配对错误的一对则远离。

对比学习:CLIP 一类的图文对比

学习这种对齐的代表性方法是对比学习。CLIP 一类模型会收集大量的(图像, 说明文字)配对。在一个 batch 内,把正确配对当作正样本(positive),把其余所有组合当作负样本(negative),训练目标是提高正样本对的相似度、降低负样本对的相似度。

相似度通常用归一化嵌入的内积(余弦相似度)计算。损失采用双向 InfoNCE 的形式,同时考虑从图像找文本、以及从文本找图像两个方向。

对比学习损失(不使用美元符号书写)

batch 大小 N,嵌入维度 D
图像嵌入 I in R^(N x D),文本嵌入 T in R^(N x D)
每一行做 L2 归一化。

logit 矩阵:  logits = (I dot T^T) * exp(tau)
             shape = N x N
对角线元素(i==j)是正确配对。

图像->文本损失:  CE(logits,        labels=[0..N-1])
文本->图像损失:  CE(logits^T,      labels=[0..N-1])
最终损失 = (loss_i2t + loss_t2i) / 2

tau:可学习的温度(temperature)参数(对数尺度)
CE:交叉熵

对比学习的优势在于不需要人工逐条打标签。仅凭从网络上收集的图像及其周边文本(alt 文本、说明文字),就能完成弱监督(weakly supervised)训练。由此得到零样本分类之类强大的迁移能力——只需比较文本提示("a photo of a cat")的嵌入与图像嵌入即可完成分类。

对齐的其他路径

对比学习并不是唯一的对齐方法。匹配/生成描述(看图生成文本)这类生成式目标同样能连接模态。实际的大模型往往会混用对比目标、生成目标、掩码重建目标等。无论哪种方式,核心问题都是一样的:如何让不同模态的表示共享同一份含义。

深入正题:融合方式

如果说对齐是让表示彼此靠近,融合就是把多个模态的信息真正结合起来、做出一个判断。按照融合发生的时机,大致分为三类。

Early fusion(早期融合)

在输入阶段就把各模态合并成一个序列,送入同一个骨干网络。把图像图块嵌入与文本 token 嵌入拼接起来,一起通过单一 Transformer,是最典型的做法。

Early fusion

[img_patch_1 ... img_patch_M, txt_tok_1 ... txt_tok_K]
        |
   单一 Transformer(全区间 self-attention)
        |
   融合表示 -> 输出

优点是从一开始就有丰富的跨模态交互。缺点是输入序列变长、计算开销增大,且必须统一各模态的预处理结构。

Late fusion(后期融合)

各模态分别用独立编码器处理到底,最后才把表示合并(拼接、平均、加权求和等)。CLIP 的推理阶段实际上就接近后期融合。两个编码器互相独立,便于模块化和缓存,但细粒度的交互不足。

Late fusion

图像 -> 图像编码器 -> z_image ─┐
文本 -> 文本编码器 -> z_text  ─┤-> 合并(拼接/内积) -> 输出

Cross-attention fusion(交叉注意力融合)

两个模态分别编码,但在中间插入交叉注意力层,让一个模态可以参照另一个模态。常见结构是文本解码器把图像特征当作 key/value 来参照。现代 VLM 的适配器/投影器 + LLM 解码器组合,广义上也属于这一路。

Cross-attention fusion

图像 -> 视觉编码器 -> 视觉特征(key/value 来源)
                                  |
文本 -> LLM 解码器 -- cross-attn --> 参照视觉特征
                                  |
                              输出 token

三种方式并不互斥。实际模型往往是用视觉编码器把图像嵌入(带 late 的性质),再用投影器对齐到 LLM 的输入空间,之后在 LLM 内部与文本混合(带 early/cross 的性质)。

视觉-语言适配器/投影器

现代 VLM 的典型结构是这样的:ViT 系列视觉编码器把图像转成图块特征,适配器(投影器)再把它映射到 LLM 的 token 嵌入空间。适配器可以是简单的 MLP,也可以是用可学习查询压缩信息的 Q-Former 一类模块。结果是图像以"虚拟 token"的形式混入 LLM 序列,与文本一起被处理。

现代 VLM 流水线(概念)

图像 -> ViT 视觉编码器 -> 图块特征(M x D_v)
                              |
                         投影器/适配器(MLP 或 Q-Former)
                              |
                         视觉 token(M' x D_llm)
                              |
[视觉 token ... 文本 token] -> LLM 解码器 -> 回答

训练流水线:从预训练到微调

多模态模型的训练通常分为两个阶段。

第一阶段:大规模预训练

用大量弱监督数据(网络上的图文配对等)学习对齐与基础表示。这一阶段常常冻结(freeze)视觉编码器,或只训练其中一部分,优先让适配器与部分 LLM 完成对齐。目的是把模态拉入同一个空间。

第二阶段:多任务/指令微调

把 VQA、生成描述、文档理解、基于 OCR 的推理等多种任务汇总成指令格式来微调。这一阶段有时会解冻(unfreeze)视觉编码器,做更精细的适配。分阶段调节冻结/解冻是稳定收敛的关键。

下面是训练循环的伪代码,用来展示流程而非真实实现。

# 多模态对比预训练伪代码(仅用于说明概念)
import torch
import torch.nn.functional as F

def clip_step(images, texts, image_encoder, text_encoder, logit_scale, optimizer):
    # 1) 分别编码各模态
    img_feat = image_encoder(images)      # (N, D)
    txt_feat = text_encoder(texts)        # (N, D)

    # 2) L2 归一化 -> 基于余弦相似度比较
    img_feat = F.normalize(img_feat, dim=-1)
    txt_feat = F.normalize(txt_feat, dim=-1)

    # 3) 相似度 logits(施加温度)
    scale = logit_scale.exp()
    logits_per_image = scale * img_feat @ txt_feat.t()   # (N, N)
    logits_per_text = logits_per_image.t()

    # 4) 以对角线为正确答案的双向交叉熵
    n = images.size(0)
    labels = torch.arange(n, device=images.device)
    loss_i2t = F.cross_entropy(logits_per_image, labels)
    loss_t2i = F.cross_entropy(logits_per_text, labels)
    loss = (loss_i2t + loss_t2i) / 2

    # 5) 反向传播
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    return loss.item()
# 指令微调阶段的冻结/解冻控制(仅用于说明概念)
def configure_trainable(model, stage):
    if stage == "align":
        # 第一阶段:冻结视觉编码器,主要训练适配器
        for p in model.vision_encoder.parameters():
            p.requires_grad = False
        for p in model.adapter.parameters():
            p.requires_grad = True
    elif stage == "instruct":
        # 第二阶段:解冻部分视觉编码器 + 微调 LLM
        for p in model.vision_encoder.parameters():
            p.requires_grad = True
        for p in model.llm.parameters():
            p.requires_grad = True
    return model

数据:规模与质量

多模态性能很大程度上取决于数据。要看两个维度。

  • 规模(scale):网络规模的图文配对提供了多样性,但噪声也多。错误的说明文字、无关的 alt 文本、重复内容都很常见。
  • 质量(quality):通过过滤(基于相似度的清洗)、去重、安全过滤、说明文字重写(re-captioning)来提升质量。近来用模型生成的高质量说明文字来增强数据的做法也很常见。

数据侧的一个陷阱是分布偏差。若偏向特定语言、特定文化圈的图像,在其他领域的表现就会下降。若目标是 OCR 或文档理解,就必须包含足够多文字丰富的图像。

数据流水线(概念)

原始采集 -> 去重 -> 相似度过滤(图文匹配) ->
安全过滤 -> 说明文字重写/增强 -> 打乱/分片 -> 训练

评估:测量什么、如何测量

多模态模型的评估按任务划分。

  • 零样本分类/检索:用训练中未见过的标签分类,或图文互相检索的准确率(Recall@K)。
  • VQA:基于图像的问答准确率。
  • 生成描述:生成说明文字的质量(基于参照的指标以及人工评估)。
  • 文档/OCR 理解:能否准确读取并推理表格、图表、文档中的信息。
  • 幻觉测量:专门评估是否编造出图像中不存在物体的基准。

只看单一指标容易产生误判。自动指标表现好,人看起来却可能不自然,反过来也一样。因此让自动指标与人工评估并行是标准做法。

局限与幻觉

多模态模型的代表性局限是幻觉(hallucination)。模型可能提及图像中不存在的物体,或被文本先验知识牵着走而误读图像。原因是多方面的。

  • 语言先验(prior)的影响过大:LLM 解码器能力太强,会在缺乏图像依据的情况下生成看似合理的答案。
  • 对齐不足:视觉特征没有充分对齐到 LLM 空间时,会漏掉细节。
  • 数据噪声:用错误的说明文字训练,会学到错误的关联。

缓解方法包括更强的对齐训练、强制以图像为依据的训练目标、基于幻觉评估的数据清洗,以及在推理时通过提示设计强制模型显式参照图像区域。即便如此,完全消除仍很困难,应用中应假设不确定性并据此设计。

其他局限还包括高分辨率/长视频处理的成本、模态不均衡(相较文本,视频数据更少),以及评估本身的难度。

深入看对比学习

对比学习是多模态对齐的引擎。但要真正训练好它,有几个细节是决定性的。表面上损失很简单,但结果会随负样本数量、温度、batch 构成而大幅变化。

负样本与 batch 大小

在 InfoNCE 损失中,负样本(negative)的数量取决于 batch 大小。一个 batch 里有 N 对样本,每个正样本自动就有 N-1 个负样本。因此 batch 越大,要解的对比问题就越难,表示也会越锐利。这正是对比学习偏好大 batch 的原因。

batch 大小与负样本数(概念)

batch N=256  -> 每个正样本对应 255 个负样本
batch N=4096 -> 每个正样本对应 4095 个负样本

负样本越多:
  - 对比难度上升 -> 往往提升表示质量
  - 显存需求增加
应对:跨设备收集(gather)嵌入以扩大负样本池

跨多个 GPU 收集嵌入来扩大负样本池是常见做法。让每个设备不只看自己的 batch,而是共享全部嵌入作为负样本,实际上就获得了更大 batch 的效果。

温度参数的作用

温度(temperature)控制相似度分布的锐利程度。温度低(即 scale 大)时,模型被迫更强烈地区分正负样本;温度高时,分布变得平滑。把温度设为可学习参数,模型就能自行找到合适的锐利度。

温度的效果(概念)

logits = (归一化嵌入内积) * scale,  scale = exp(tau)

scale 大(温度低):分布锐利 -> 强对比,但有训练不稳定的风险
scale 小(温度高):分布平滑 -> 弱对比

实务:把 tau 设为可学习参数,但设上限以防止失控

难负样本

不是所有负样本都同样有用。容易区分的负样本(完全无关的一对)训练信号弱,容易混淆的负样本(含义相近但不同的一对)则给出强信号。有意加入这类难负样本(hard negative)能提升细粒度的区分能力。不过一旦存在标签噪声,把真正的正样本误判为负样本的风险也会随之增大。

实例演练:零样本分类是怎么运作的

来具体追踪一下,经对比学习对齐后的模型是如何在没有标签的情况下完成分类的。关键在于把分类问题转化为"图文检索"问题。

零样本分类流程(概念)

1) 为每个候选类别生成提示词
   "a photo of a cat", "a photo of a dog", ...
2) 用文本编码器嵌入每个提示词 -> t_1, t_2, ...
3) 嵌入输入图像 -> v
4) 计算 v 与每个 t_k 的余弦相似度
5) 预测相似度最高的类别

核心:即便训练时从未见过这个标签,
     由于文本空间里的含义已经对齐,分类依然成立

同样的流程也适用于检索。因为图像嵌入与文本嵌入位于同一空间,用文本找图像(text-to-image)和用图像找文本(image-to-text)的双向检索都能实现。对齐的威力,正体现在这种跨模态能力上。

与生成式多模态的联系

到目前为止讨论的都是理解(understanding)方向,但多模态还有另一条主线——生成。用文本生成图像,或看图写出长篇描述。对齐与融合的原理在生成任务里同样成立。

  • 图像 -> 文本生成(生成描述、VQA):把视觉特征注入 LLM,LLM 以此为条件自回归地生成文本。前面提到的适配器+LLM 结构原样适用。
  • 文本 -> 图像生成:以文本嵌入为条件生成图像。扩散模型或基于 VQ 的自回归生成是代表性方法。此处文本-图像对齐的质量决定了生成结果的保真度。
理解型 vs 生成型(概念)

理解型:[图像+文本] -> 理解/判断 -> 文本答案
生成型(生成描述):[图像] -> 条件 -> 自回归生成文本
生成型(T2I):[文本] -> 条件 -> 生成图像(扩散/VQ 自回归)

共同点:模态对齐的质量是所有任务的基础

这两条主线并非互相分离,而是站在同一个基础(对齐后的表示)之上。好的对齐会同时提升理解与生成两方面的表现。

训练稳定性与扩展规模

大规模多模态训练很容易变得不稳定。不同模态的损失量级不同,视觉编码器与 LLM 的学习速度不同,数据噪声又会让损失剧烈波动。有一些实务手段可用于稳定训练。

  • 学习率分离:给视觉编码器、适配器、LLM 设置不同的学习率。通常新初始化的适配器学习率高,预训练好的视觉编码器学习率低。
  • 预热与调度:初期用预热缓和过大的梯度,后期用余弦衰减等方式稳定训练。
  • 梯度裁剪:防止噪声数据引发梯度爆炸。
  • 分阶段解冻:按照前面提到的冻结/解冻计划,在对齐稳定之后再释放更多参数。
各模块学习率示例(概念,相对值)

适配器/投影器 : 高(全新学习)
LLM          : 中(微调)
视觉编码器    : 低(保留预训练成果)

原则:新初始化的部分要学得快,
     已经有良好表示的部分要学得慢

在扩展规模方面,让数据、模型、算力均衡增长很重要。只放大其中一项,收益会很快递减。数据质量跟不上,光放大模型也不会改善对齐;反过来数据再多,模型容量不够也无法吸收。

多语言与 OCR 的考量

要把多模态模型用于多语言文档或 OCR,数据构成上需要特别留意。一般的网络图文数据,可能没有包含足够多文字丰富的图像(文档、表格、图表、标牌)。

面向 OCR/文档理解的数据增强(概念)

仅用常规数据 : 以自然图像为主 -> 文字读取能力弱
增强之后     : 加入文档/表格/图表/截图/标牌
              + 多语言文字图像
              -> 提升 OCR-free 文档理解能力

核心:确保待读取文字位于图像内部的样本占有足够比例

在多语言场景中,若某些语言(尤其是非拉丁字母的语言)代表性不足,该语言的 OCR 与理解能力就会下降。语言平衡、文字体系多样性,以及刻意纳入含该语言文字的图像,都很重要。

实务应用场景

来看几个场景,了解上面梳理的原理在实际应用中如何组合。

  • 图像生成描述/替代文字生成:用视觉编码器 + 适配器 + LLM 的组合来描述图像。为了减少幻觉,强调图像依据的微调很重要。
  • 文档问答:以高分辨率/动态分辨率处理文档,以 OCR-free 的方式读取表格、图表来回答。数据中文档图像的占比是决定性因素。
  • 图文检索:把经对比学习对齐的嵌入建立索引,实现双向检索。嵌入质量决定检索准确率。
  • 多模态助手:交织多种模态的对话。上下文成本管理与幻觉缓解是核心课题。

每个场景归根结底都是同样两个原理(对齐、融合)的不同组合。对齐哪些模态、对齐到什么程度、在哪个时点融合,决定了应用的性格。

对比:对齐与融合方式一览

分类代表技术优点缺点
对齐目标对比(InfoNCE)弱监督,零样本迁移能力强对精细生成不足
对齐目标生成/生成描述精细的语言生成能力对齐信号是间接的
融合early交互丰富序列长,开销大
融合late便于模块化、缓存交互较弱
融合cross-attn兼顾开销与交互结构复杂

结语

多模态学习的核心可以归结为两点。第一,把不同的模态对齐到同一个语义空间;第二,按任务需要把这些表示融合起来。对比学习仅凭弱监督数据就打造出了强大的对齐能力,而结合适配器与 LLM 的现代 VLM,把这种对齐进一步扩展成了丰富的生成能力。

与此同时,幻觉与数据偏差这样的课题依然存在。规模与质量的平衡、分阶段的冻结/解冻、审慎的评估,是打造优秀多模态模型的实质性杠杆。下一篇将讨论如何把图像和音频真正转换成 token 并编织成一个序列——token 化与融合的具体细节。

参考资料