拆解多模态大模型:视觉编码器、Projector与LLM
摘要: 大语言模型原本只能处理文字,它究竟是怎么获得“看图”能力的?对于很多多模态大模型来说,答案并不是重新训练一个从像素到文字的超级模型,而是把已经成熟的视觉模型与语言模型连接起来。一套典型的多模态架构,可以拆成三个核心组件:视觉编码器(Visual Encoder)负责“看”,Projector负责连接视觉与语言,LLM负责理解、推理和生成。
一、多模态大模型,本质上是怎么拼起来的?
先不讨论复杂的模型名称。
无论是LLaVA,还是许多采用类似思路构建的视觉语言模型,都可以先抽象成一条非常简单的流水线:
这套架构里,三个组件的分工非常明确:
- 视觉编码器:负责看图片
- Projector:负责连接视觉模型和语言模型
- LLM:负责理解、推理和回答
为什么需要这么麻烦?因为LLM原本并不会处理图片。我们输入一句:
图片里有什么?
对于LLM来说,这句话最终会被Tokenizer转换成一串文本Token,再进入模型。但一张图片最开始只是一个由RGB像素组成的矩阵。对于一个只在文字上训练过的语言模型来说,这些像素没有直接意义。也就是说:**图片不能直接塞进纯文本LLM。**因此,多模态模型首先要解决的,就是:
怎样把图片转换成一种LLM能够处理的信息?
视觉编码器和Projector,就是为了解决这个问题而存在的。
二、视觉编码器:先把图片变成视觉Token
视觉编码器可以理解成多模态模型的“眼睛”。它不负责聊天,也不负责生成答案。它的核心任务只有一个:
把原始图片转换成一组有意义的视觉特征。
目前常见的视觉编码器通常建立在Vision Transformer,也就是ViT一类架构之上。CLIP Vision Encoder、SigLIP等,都属于常见选择。
2.1 图片为什么要切成Patch?
假设我们输入一张图片。模型通常不会把整张图片一次性当作一个整体处理,而是先把它切成很多小块。这些小块通常叫:
Patch。
可以把它理解成拼图。一张图片先被拆成很多小块,然后每个Patch经过处理,变成一个高维向量。
整个过程可以简化成:
例如一张图片中有:
- 一个人
- 一辆汽车
- 一棵树
- 蓝色天空
- 道路
- 建筑
视觉编码器不会直接输出:
“这是一个人在汽车旁边。”
它输出的是一串高维向量。这些向量携带图片中的颜色、纹理、形状、局部物体、空间位置以及更高层语义信息。因此到了这一步:
图片已经从“像素”变成了“视觉特征序列”。
这也是视觉编码器最重要的作用。
2.2 视觉Token和文本Token是一回事吗?
不是。
这是理解Projector之前必须先弄明白的一点。虽然它们都可以被称为Token,但来源完全不同。文本Token来自语言模型的词表和Embedding系统。视觉Token则来自视觉编码器。两者分别由不同模型、不同训练目标学习出来,因此它们所在的特征空间并不天然一致。可以把它们想象成:
视觉编码器已经看懂了一部分图片,但它说的是“视觉模型的语言”。
而LLM听得懂的是:
“语言模型自己的语言”。
于是问题来了:谁负责在中间翻译? 答案就是Projector。
三、Projector:视觉世界和语言世界之间的桥
Projector也经常被称为:
- Multimodal Projector
- Vision-Language Connector
- Modal Bridge
- 模态桥接器
虽然名字不同,但核心思想是一致的。
它位于:
视觉编码器和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。
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与视觉特征进行交互,最后输出固定数量的视觉表示。
因此:
它最大的优势是:
可以形成一个信息瓶颈。
假设视觉编码器产生大量视觉Token,Q-Former不一定需要把它们全部交给LLM。
它可以把视觉信息浓缩成固定数量的表示。
这样就有机会减少LLM需要处理的视觉Token数量。
代价则是:
结构和训练方式比Linear、MLP复杂得多。
所以MLP和Q-Former不能简单理解成:
谁先进,谁落后。
它们实际上代表两种不同的设计思路。
| 方案 | 核心思路 | 优势 | 代价 |
|---|---|---|---|
| Linear | 直接线性映射 | 最简单、参数少 | 表达能力有限 |
| MLP | 非线性映射 | 简单与能力之间较平衡 | 通常不主动压缩Token |
| Q-Former | Query主动提取视觉信息 | 可以压缩和筛选信息 | 架构和训练更复杂 |
因此Projector设计真正面对的矛盾是:
究竟应该保留多少视觉信息,又应该为这些信息付出多少计算成本?
五、LLM到底是怎样“看到”图片的?
讲完Projector,我们再看最后一个组件:
LLM。
这里有一个非常关键的事实:
LLM本身并没有突然学会读取RGB像素。
它仍然是在处理Token。
区别只是:
以前输入基本都是文本Token。
现在输入里面多了一组:
视觉Token。
例如你上传一张图片,然后问:
它在做什么?
整个过程可以简化成:
假设图片里是一只狗在草地上奔跑。
视觉编码器首先提取图片信息。
Projector再把这些信息转换成LLM可以利用的视觉表示。
与此同时:
“它在做什么?”
会被转换成普通文本Token。
最后,LLM接收到的可以简单理解成:
视觉Token + 文本Token
LLM利用两者共同形成的上下文进行推理,然后输出:
一只狗正在草地上奔跑。
所以从这个角度看,多模态LLM的核心并不是:
“让语言模型突然学会看像素。”
而是:
把不同模态的信息转换成LLM可以共同处理的表示。
这个思路不只适用于图片。
理论上,音频、视频等信息,也可以寻找类似的方式进入语言模型。
六、视觉编码器和LLM原本不认识,怎么训练到一起?
还有一个很自然的问题:
视觉编码器和LLM原本是两个完全独立的模型。
在中间加一个Projector,它们为什么就能配合?
答案是:
训练和对齐。
以LLaVA这类方法为例,可以把训练过程简化成两个阶段。
第一阶段:先把桥接起来
一开始,视觉编码器和LLM都已经拥有很强的单模态能力。
因此没有必要把所有能力推倒重练。
一种典型做法是:
先冻结大部分已有模型,重点训练中间的Projector。
通过大量图片和文本对应数据,让Projector逐渐学会:
什么样的视觉特征,应该转换成什么样的语言模型表示。
这一步主要解决的是:
视觉与语言怎样接上线。
第二阶段:再学会怎么回答问题
只连接起来还不够。
模型还需要知道:
- 用户问的是什么?
- 图片中哪些内容与问题有关?
- 应该怎样组织答案?
- 怎样进行多轮视觉问答?
因此还需要使用:
多模态指令数据。
例如:
图片:一辆汽车停在路边
问题:这辆车是什么颜色?
回答:红色。
或者:
图片:一张统计图
问题:哪个季度销售额最高?
回答:第四季度。
经过这一阶段之后,模型才会逐渐从:
“我能够接收到视觉信息”
变成:
“我知道应该怎样利用视觉信息回答用户的问题。”
所以整个过程可以概括成两句话:
第一步,让视觉和语言接上线。
第二步,让模型学会怎样使用视觉信息。
七、纯文本LLM也能“外挂”视觉能力吗?
理解了前面的结构之后,我们就可以回答一个很现实的问题:
如果我手里有一个很强的纯文本LLM,但它本身不能看图片,能不能给它加一个“眼睛”?
答案是:
可以,但要区分两种完全不同的方案。
7.1 真正的模型内部多模态
第一种就是我们前面一直讲的:
视觉编码器 → Projector → LLM
这种情况下,图片信息最终会以视觉Token的形式进入LLM。
这可以称为真正意义上的:
模型内部多模态。
但通常需要:
- 能够访问模型权重
- 训练Projector
- 准备视觉语言数据
- 进行多模态对齐训练
因此工程门槛比较高。
7.2 外部视觉代理
还有一种更加容易实现的思路:
不用修改纯文本LLM。
而是在它前面加一个视觉模型。
流程如下:
比如用户上传一张图片。
前面的视觉模型先输出:
图片中有一辆红色汽车停在路边,两个人站在汽车旁边。
然后代理层把这段描述加上用户的问题:
根据下面的图片描述回答问题:
图片中有一辆红色汽车停在路边,两个人站在汽车旁边。
用户问题:车旁边有几个人?
再交给纯文本LLM。
LLM自然可以回答:
两个人。
从用户体验来看:
这个纯文本LLM似乎也会“看图”了。
但两种方案存在一个根本区别。
真正的多模态模型里:
LLM能够直接利用经过编码的视觉信息。
而代理方案里:
LLM真正看到的仍然只有文字。
如果前面的视觉模型忽略了某个细节,那么后面的LLM就没有机会重新查看原始图片。
因此,对于:
- 图片大意
- 普通物体识别
- OCR文字提取
- 简单图片问答
代理方案可能已经很好用。
但是遇到:
- 复杂图表
- 空间关系
- 很小的局部细节
- 高精度OCR
- 需要反复观察图片的推理任务
真正的模型内部多模态通常具有更大的发挥空间。
更多推荐

所有评论(0)