摘要: 大语言模型原本只能处理文字,它究竟是怎么获得“看图”能力的?对于很多多模态大模型来说,答案并不是重新训练一个从像素到文字的超级模型,而是把已经成熟的视觉模型与语言模型连接起来。一套典型的多模态架构,可以拆成三个核心组件:视觉编码器(Visual Encoder)负责“看”,Projector负责连接视觉与语言,LLM负责理解、推理和生成。


一、多模态大模型,本质上是怎么拼起来的?

先不讨论复杂的模型名称。

无论是LLaVA,还是许多采用类似思路构建的视觉语言模型,都可以先抽象成一条非常简单的流水线:

多模态大模型核心流水线

视觉特征

视觉Token

文本Token

图像输入

视觉编码器
Visual Encoder

模态桥接器
Projector

大语言模型
LLM

文本输入

文本回答

这套架构里,三个组件的分工非常明确:

  • 视觉编码器:负责看图片
  • Projector:负责连接视觉模型和语言模型
  • LLM:负责理解、推理和回答

为什么需要这么麻烦?因为LLM原本并不会处理图片。我们输入一句:

图片里有什么?

对于LLM来说,这句话最终会被Tokenizer转换成一串文本Token,再进入模型。但一张图片最开始只是一个由RGB像素组成的矩阵。对于一个只在文字上训练过的语言模型来说,这些像素没有直接意义。也就是说:**图片不能直接塞进纯文本LLM。**因此,多模态模型首先要解决的,就是:

怎样把图片转换成一种LLM能够处理的信息?

视觉编码器和Projector,就是为了解决这个问题而存在的。


二、视觉编码器:先把图片变成视觉Token

视觉编码器可以理解成多模态模型的“眼睛”。它不负责聊天,也不负责生成答案。它的核心任务只有一个:

把原始图片转换成一组有意义的视觉特征。

目前常见的视觉编码器通常建立在Vision Transformer,也就是ViT一类架构之上。CLIP Vision Encoder、SigLIP等,都属于常见选择。

2.1 图片为什么要切成Patch?

假设我们输入一张图片。模型通常不会把整张图片一次性当作一个整体处理,而是先把它切成很多小块。这些小块通常叫:

Patch。

可以把它理解成拼图。一张图片先被拆成很多小块,然后每个Patch经过处理,变成一个高维向量。
整个过程可以简化成:

原始图片

切分为多个Patch

Patch 1

Patch 2

Patch 3

...

Vision Transformer

视觉Token 1

视觉Token 2

视觉Token 3

...

视觉特征序列

例如一张图片中有:

  • 一个人
  • 一辆汽车
  • 一棵树
  • 蓝色天空
  • 道路
  • 建筑

视觉编码器不会直接输出:

“这是一个人在汽车旁边。”

它输出的是一串高维向量。这些向量携带图片中的颜色、纹理、形状、局部物体、空间位置以及更高层语义信息。因此到了这一步:

图片已经从“像素”变成了“视觉特征序列”。

这也是视觉编码器最重要的作用。

2.2 视觉Token和文本Token是一回事吗?

不是。

这是理解Projector之前必须先弄明白的一点。虽然它们都可以被称为Token,但来源完全不同。文本Token来自语言模型的词表和Embedding系统。视觉Token则来自视觉编码器。两者分别由不同模型、不同训练目标学习出来,因此它们所在的特征空间并不天然一致。可以把它们想象成:

视觉编码器已经看懂了一部分图片,但它说的是“视觉模型的语言”。

而LLM听得懂的是:

“语言模型自己的语言”。

于是问题来了:谁负责在中间翻译? 答案就是Projector。


三、Projector:视觉世界和语言世界之间的桥

Projector也经常被称为:

  • Multimodal Projector
  • Vision-Language Connector
  • Modal Bridge
  • 模态桥接器

虽然名字不同,但核心思想是一致的。

它位于:

视觉编码器和LLM之间。

Projector解决的问题

视觉编码器输出

视觉特征空间

Projector

LLM可接受的
视觉表示

与文本Token一起
送入LLM

3.1 为什么视觉特征不能直接交给LLM?

最容易想到的问题是:维度可能不一样。 例如视觉模型输出一种维度的向量,而LLM内部使用另一种维度。尺寸不一致,自然无法直接连接。因此Projector首先需要解决:

维度对齐

把视觉编码器输出的特征维度,转换成LLM可以接受的维度。但如果只把Projector理解成“改维度”,就太简单了。它还需要解决另外一个更加重要的问题:

语义对齐

视觉编码器和LLM原本是两个独立训练出来的模型。视觉编码器关注的是:

  • 颜色
  • 形状
  • 纹理
  • 物体
  • 空间关系

而LLM学习的是:

  • 词语
  • 语言
  • 知识
  • 逻辑
  • 上下文关系

所以Projector需要通过训练逐渐学会:

怎样把视觉模型得到的特征,转换成LLM能够利用的表示。

这里有一个很容易产生的误解。

Projector并不是:

图片 → “猫”这个文字 → LLM

它通常不会先把图片转换成一段中文。更准确的过程是:

图片 → 视觉特征 → Projector → 一组连续向量 → LLM

这些连续向量可以理解成:

专门提供给LLM的视觉Token。

所以Projector真正干的事情不是简单的“图片转文字”。

而是:

把视觉信息转换成可以进入语言模型计算体系的表示。

这也是整篇文章最重要的一个概念。


四、Projector怎么设计?从Linear到MLP,再到Q-Former

既然Projector负责搭桥,那么:

这座桥应该怎么搭?

不同模型给出了不同答案。

比较有代表性的三条路线是:

Linear、MLP和Q-Former。

视觉编码器输出
大量视觉特征

Linear

MLP

Q-Former

线性映射

结构最简单
基本保留Token数量

多层非线性映射

表达能力更强
仍然比较轻量

Learnable Query
+ Cross-Attention

主动提取视觉信息
可压缩Token数量

4.1 Linear:最简单的桥

最朴素的方法就是Linear,也就是线性映射。

原始LLaVA采用的就是这种思路。

视觉编码器输出视觉特征之后,通过一个可训练的线性Projection,将这些特征映射到LLM需要的维度。

它最大的优势就是:

简单。

没有复杂的Transformer,也没有额外的Cross-Attention。

可以把它理解成:

视觉编码器给我什么,我按照学习到的规则转换之后,就交给LLM。

这种方案参数少、结构简单,非常适合用来理解多模态连接器最基本的工作方式。

但它也存在一个问题:

基本不主动减少视觉Token数量。

视觉编码器产生大量Token,那么这些Token经过转换后,往往仍然需要进入LLM。

而Token越多,就意味着:

  • 上下文占用更多
  • 显存开销更高
  • 推理速度更慢

所以后续模型开始寻找更好的平衡。


4.2 MLP:简单,但表达能力更强

LLaVA-1.5后来做了一个很典型的改动:

把Linear Projector升级成MLP Projector。

MLP可以理解成:

不只进行一次简单映射,而是在中间增加了一些非线性变换。

不需要理解神经网络代码,也可以知道它为什么有用。

Linear更像:

按照一套相对直接的规则转换视觉特征。

而MLP则可以学习:

更复杂的视觉特征组合关系。

关键在于:

MLP并没有把架构搞得特别复杂。

它仍然是一个相对轻量的连接器。

这也是LLaVA路线非常有意思的一点:

视觉和语言之间并不一定需要一个极其复杂的桥接器。

如果视觉编码器足够强、LLM足够强、训练数据和对齐方法合适,一个结构非常简单的Projector也可以发挥很好的作用。

所以在很多多模态模型中:

MLP Projector至今依然是一种非常常见的方案。


4.3 Q-Former:不只是转换,还要“挑信息”

BLIP-2走的是另一条路线。

它引入了:

Q-Former(Querying Transformer)。

它和Linear、MLP最大的区别是:

它并不只是单纯转换视觉特征,而是主动从视觉信息中提取一部分内容。

可以把视觉编码器想象成一个资料库。

里面可能有几百个视觉Token。

Linear和MLP的思路比较像:

把这些资料转换之后交给LLM。

而Q-Former则更像:

先派出一组“查询员”,从大量视觉信息中找出最重要的部分,再交给LLM。

这些查询员就是:

Learnable Query。

它们通过Cross-Attention与视觉特征进行交互,最后输出固定数量的视觉表示。

因此:

Cross-Attention

大量视觉Token

Q-Former

Learnable Queries
可学习Query

提取重要视觉信息

固定数量的视觉Token

LLM

它最大的优势是:

可以形成一个信息瓶颈。

假设视觉编码器产生大量视觉Token,Q-Former不一定需要把它们全部交给LLM。

它可以把视觉信息浓缩成固定数量的表示。

这样就有机会减少LLM需要处理的视觉Token数量。

代价则是:

结构和训练方式比Linear、MLP复杂得多。

所以MLP和Q-Former不能简单理解成:

谁先进,谁落后。

它们实际上代表两种不同的设计思路。

方案核心思路优势代价
Linear直接线性映射最简单、参数少表达能力有限
MLP非线性映射简单与能力之间较平衡通常不主动压缩Token
Q-FormerQuery主动提取视觉信息可以压缩和筛选信息架构和训练更复杂

因此Projector设计真正面对的矛盾是:

究竟应该保留多少视觉信息,又应该为这些信息付出多少计算成本?


五、LLM到底是怎样“看到”图片的?

讲完Projector,我们再看最后一个组件:

LLM。

这里有一个非常关键的事实:

LLM本身并没有突然学会读取RGB像素。

它仍然是在处理Token。

区别只是:

以前输入基本都是文本Token。

现在输入里面多了一组:

视觉Token。

例如你上传一张图片,然后问:

它在做什么?

整个过程可以简化成:

LLMProjector视觉编码器用户LLMProjector视觉编码器用户上传图片提取视觉特征视觉特征序列转换后的视觉Token文本问题Token联合理解视觉+文本生成文字回答

假设图片里是一只狗在草地上奔跑。

视觉编码器首先提取图片信息。

Projector再把这些信息转换成LLM可以利用的视觉表示。

与此同时:

“它在做什么?”

会被转换成普通文本Token。

最后,LLM接收到的可以简单理解成:

视觉Token + 文本Token

LLM利用两者共同形成的上下文进行推理,然后输出:

一只狗正在草地上奔跑。

所以从这个角度看,多模态LLM的核心并不是:

“让语言模型突然学会看像素。”

而是:

把不同模态的信息转换成LLM可以共同处理的表示。

这个思路不只适用于图片。

理论上,音频、视频等信息,也可以寻找类似的方式进入语言模型。


六、视觉编码器和LLM原本不认识,怎么训练到一起?

还有一个很自然的问题:

视觉编码器和LLM原本是两个完全独立的模型。

在中间加一个Projector,它们为什么就能配合?

答案是:

训练和对齐。

以LLaVA这类方法为例,可以把训练过程简化成两个阶段。

已有视觉编码器

第一阶段:视觉-语言对齐

已有LLM

主要训练Projector

视觉特征能够进入
LLM表示空间

第二阶段:多模态指令训练

图片 + 问题 + 回答数据

模型学会根据图片
理解并回答问题

第一阶段:先把桥接起来

一开始,视觉编码器和LLM都已经拥有很强的单模态能力。

因此没有必要把所有能力推倒重练。

一种典型做法是:

先冻结大部分已有模型,重点训练中间的Projector。

通过大量图片和文本对应数据,让Projector逐渐学会:

什么样的视觉特征,应该转换成什么样的语言模型表示。

这一步主要解决的是:

视觉与语言怎样接上线。


第二阶段:再学会怎么回答问题

只连接起来还不够。

模型还需要知道:

  • 用户问的是什么?
  • 图片中哪些内容与问题有关?
  • 应该怎样组织答案?
  • 怎样进行多轮视觉问答?

因此还需要使用:

多模态指令数据。

例如:

图片:一辆汽车停在路边
问题:这辆车是什么颜色?
回答:红色。

或者:

图片:一张统计图
问题:哪个季度销售额最高?
回答:第四季度。

经过这一阶段之后,模型才会逐渐从:

“我能够接收到视觉信息”

变成:

“我知道应该怎样利用视觉信息回答用户的问题。”

所以整个过程可以概括成两句话:

第一步,让视觉和语言接上线。

第二步,让模型学会怎样使用视觉信息。


七、纯文本LLM也能“外挂”视觉能力吗?

理解了前面的结构之后,我们就可以回答一个很现实的问题:

如果我手里有一个很强的纯文本LLM,但它本身不能看图片,能不能给它加一个“眼睛”?

答案是:

可以,但要区分两种完全不同的方案。

7.1 真正的模型内部多模态

第一种就是我们前面一直讲的:

视觉编码器 → Projector → LLM

这种情况下,图片信息最终会以视觉Token的形式进入LLM。

这可以称为真正意义上的:

模型内部多模态。

但通常需要:

  • 能够访问模型权重
  • 训练Projector
  • 准备视觉语言数据
  • 进行多模态对齐训练

因此工程门槛比较高。


7.2 外部视觉代理

还有一种更加容易实现的思路:

不用修改纯文本LLM。

而是在它前面加一个视觉模型。

流程如下:

纯文本LLM视觉模型视觉代理层用户纯文本LLM视觉模型视觉代理层用户图片 + 问题请理解这张图片返回图片描述/识别结果图片信息转换为文字图片描述 + 用户问题生成最终回答返回结果

比如用户上传一张图片。

前面的视觉模型先输出:

图片中有一辆红色汽车停在路边,两个人站在汽车旁边。

然后代理层把这段描述加上用户的问题:

根据下面的图片描述回答问题:
图片中有一辆红色汽车停在路边,两个人站在汽车旁边。
用户问题:车旁边有几个人?

再交给纯文本LLM。

LLM自然可以回答:

两个人。

从用户体验来看:

这个纯文本LLM似乎也会“看图”了。

但两种方案存在一个根本区别。

用户上传图片

视觉能力在哪里?

模型内部多模态

外部视觉代理

视觉编码器

Projector

视觉Token进入LLM

视觉与文本联合推理

独立视觉模型

先生成文字描述

纯文本LLM

LLM实际只看到文字

真正的多模态模型里:

LLM能够直接利用经过编码的视觉信息。

而代理方案里:

LLM真正看到的仍然只有文字。

如果前面的视觉模型忽略了某个细节,那么后面的LLM就没有机会重新查看原始图片。

因此,对于:

  • 图片大意
  • 普通物体识别
  • OCR文字提取
  • 简单图片问答

代理方案可能已经很好用。

但是遇到:

  • 复杂图表
  • 空间关系
  • 很小的局部细节
  • 高精度OCR
  • 需要反复观察图片的推理任务

真正的模型内部多模态通常具有更大的发挥空间。


更多推荐