一个大语言模型(LLM)的世界是由 token 构成的——一串离散的符号,每个都对应词表里的一项。它从不「看见」任何东西,它只是在预测下一个 token。那么,要让这样一个纯文本的大脑理解一张照片,核心难题只有一个:
怎样把一张连续的、二维的图像,变成 LLM 能吞下的那种 token? 这个问题的不同答案,几乎决定了一个视觉语言模型的全部性格。LLaVA 和 Qwen2-VL 之所以如此不同,根子就在它们对这一个问题的回答上。
这篇文章会带你从这个最根本的问题出发,先搭起所有 VLM 共享的通用骨架,再分别拆开 LLaVA 与 Qwen2-VL 的内部结构,把它们逐一对照,最后把镜头拉远,看看这两者在整个多模态领域演化版图里各自站在哪里。读完你会发现,它们的差异不是细节之争,而是两种设计哲学的分野。
Part 1 — 通用配方
所有 VLM 都长这样:三件套
抛开细节,几乎每一个现代视觉语言模型都是同一个三明治结构:一个视觉编码器 负责看,一个语言模型 负责说,中间夹着一个连接器(connector) 负责翻译。连接器是整个故事的关键——它把视觉世界的表示,翻译成语言世界的「方言」。
图 1 · 视觉语言模型的通用骨架
输入图像
"图里有什么?"
视觉编码器
ViT
把图切成 patch
连接器
connector
翻译到词向量空间
语言模型
LLM (decoder)
"一只猫坐在
窗台上。"
三件套: 视觉编码器把图像切成 patch 编码成视觉 token ,连接器把它们投影进 LLM 的词向量空间,然后这些视觉 token 和文本 token 一起喂给语言模型生成回答。LLaVA 和 Qwen2-VL 共享这个骨架,差异全在每个零件的具体实现上。
核心动作:把图像「切碎」成 token
视觉编码器几乎都是 Vision Transformer(ViT) 。它的第一步叫 patchify ——把图像切成一个个固定大小的小方块(patch),每个 patch 被压成一个向量。一张图于是变成一串向量,正好对应 LLM 眼里的一串 token。patch 越小、图越大,token 就越多。
图 2 · Patchify:一张图如何变成一串 token
1
图像 → 4×4 个 patch
展平
展平成 16 个视觉 token 的序列
1
2
3
4
5
6
···
16
每个 token = 一个 patch 的向量表示
这一步是理解后面所有差异的钥匙:token 的数量直接由「图多大、patch 多大」决定 。LLaVA 选择把所有图都缩到同一个尺寸,于是 token 数永远固定;Qwen2-VL 选择让图保留原始尺寸,于是 token 数随图而变。一个根本的分叉,就从这里开始。
Part 2 — LLaVA
把世界压进一个固定的方格
LLaVA(Large Language and Vision Assistant)是 2023 年奠定整个范式的作品。它的设计哲学可以用两个字概括:简单 。视觉编码器用现成的 CLIP,连接器只是一个小小的多层感知机(MLP),其余全交给 LLM。正是这种极简,让它成为最适合入门、也最常被复现的基线。
图 3 · LLaVA-1.5 的结构:固定 336×336,固定 576 个 token
任意图像
→ 强制缩放
到 336×336
CLIP ViT-L/14
patch=14 · 冻结
→ 24×24 patch
2 层 MLP
projector
···
576 个视觉 token
永远是 576,不多不少
Vicuna
(LLaMA 系 LLM)
关键点: 无论你喂进来的是一张证件照还是一张高清地图,LLaVA 都先把它强行缩放成 336×336 ,因此 ViT 永远吐出 24×24=576 个 patch,连接器永远输出 576 个视觉 token。这个「固定」是 LLaVA 一切优点(简单)与一切缺点(吃不下细节)的共同来源。
为什么是 576?一道小学算术
这个数字不是魔法,而是直接算出来的。CLIP ViT-L/14 的 patch 边长是 14 像素,输入边长是 336:
# 每条边的 patch 数
336 ÷ 14 = 24
# 二维网格的 patch 总数 = 视觉 token 数
24 × 24 = 576 个 token
记住这个心算方法(边长 ÷ patch_size,再平方),后面看 Qwen2-VL 时你会用同样的方法,算出一个完全不同的、会浮动的数字。
LLaVA 怎么训练:两段式
LLaVA 的训练分两步,理解这两步对你做后训练(尤其是 SFT 阶段)非常重要,因为它决定了「哪些部件被冻结、哪些被更新」。
图 4 · LLaVA 的两段式训练:先学翻译,再学听话
阶段 1 · 特征对齐
558K 图文对 · 只训练连接器
ViT
❄ 冻结
连接器
🔥 训练
LLM
❄ 冻结
目标:让连接器学会把视觉特征
翻译成 LLM 听得懂的「词」
阶段 2 · 视觉指令微调
~665K 指令数据 · 训练连接器 + LLM
ViT
❄ 冻结
连接器
🔥 训练
LLM
🔥 训练
目标:让模型学会看着图
遵循各种指令、对话
先连线,再上岗。 阶段 1 只动连接器,先把「视觉→语言」这座桥搭通;阶段 2 再解冻 LLM,教整个系统看图听话。你做项目里的 SFT(Phase 1)其实就是阶段 2 的延续——通常用 LoRA 在这个基础上继续教模型你关心的任务。
LLaVA-1.5 改了什么
初代 LLaVA 的连接器只是一个线性层。LLaVA-1.5 做了三个朴素但有效的升级:把连接器换成 2 层 MLP 、提高输入分辨率到 336、并加入大量学术 VQA 数据。这三招让它成了之后两年最常用的开源基线。再后来的 LLaVA-NeXT(1.6) 引入了 AnyRes ——把高清大图切成几块分别过 ViT——这其实是在为「固定分辨率」这个原罪打补丁,也预示了下一代模型的方向。
LLaVA 的阿喀琉斯之踵
固定 336×336 意味着:一张细长的网页截图会被压扁、一张 4K 的文档照片会糊成一团、一段视频更是无从下手。当信息的密度超过 576 个 token 能承载的上限,LLaVA 就看不清了。 这正是 Qwen2-VL 要解决的问题。
Part 3 — Qwen2-VL
让图像保留它自己的形状
如果说 LLaVA 的哲学是「把世界裁剪成我能处理的样子」,那 Qwen2-VL 的哲学正好相反:让模型去适应世界本来的样子 。这个转变带来三项核心创新:动态分辨率、token 合并、以及多模态位置编码 M-RoPE。
图 5 · Naive Dynamic Resolution:token 数随图而变
小图
224×224
~66 token
大图 / 高清文档 1280×800
···
上千个 token
对比 · LLaVA 的做法
不论大小
都缩到 336²
···
永远 576 token
大图被压缩、细节丢失 ✗
核心区别一图说尽: Qwen2-VL 给小图少量 token、给大图大量 token,信息密度和 token 预算成正比;LLaVA 则把所有图都塞进同一个 576 的盒子里。处理文档、长截图、细密表格时,这个差异是决定性的。
改造一:动态分辨率,需要先动 ViT 的位置编码
让 ViT 接受任意分辨率,有一个隐藏的麻烦:传统 ViT 用的是绝对位置编码 ——它预设了「图就是 24×24 个 patch」,一旦 patch 数量会变,这套固定的位置表就失效了。Qwen2-VL 的解法是:删掉 ViT 里的绝对位置编码,换成 2D-RoPE (二维旋转位置编码),用相对的、可外推的方式表达「第几行第几列」,这样不管多少个 patch 都能正确编码空间位置。
改造二:2×2 合并,给 token 数量「踩刹车」
动态分辨率有个副作用——大图会产生海量 token,把 LLM 的上下文撑爆。Qwen2-VL 在 ViT 之后接一个小 MLP,把相邻的 2×2 共 4 个 patch 压缩成 1 个 token ,token 数直接砍掉 4 倍,再用 <|vision_start|> 和 <|vision_end|> 把这段视觉 token 包起来。
图 6 · 2×2 token 合并:再算一次那道算术
224×224 → 16×16 = 256 patch
2×2
MLP 合并
8×8 = 64 token
# 224×224,patch=14
224 ÷ 14 = 16 → 16 × 16 = 256 patch
# 2×2 合并,÷4
256 ÷ 4 = 64 ,再 +2 个边界 token = 66
这就是为什么一张 224×224 的图进 Qwen2-VL 后是 66 个 token (64 + vision_start + vision_end),而在 LLaVA 里同样的图会被拉伸到 336 再变成固定的 576。token 预算的精打细算,是 Qwen2-VL 能同时塞下多图和长视频的前提。
改造三:M-RoPE,给文本、图像、视频一套统一的「坐标系」
这是 Qwen2-VL 最优雅的一笔。普通 LLM 的位置编码(1D-RoPE)只有一个维度——「第几个 token」,这对一行文字够用,但对一张二维的图、一段三维的视频(高 × 宽 × 时间)就太贫乏了。M-RoPE(多模态旋转位置编码)把位置拆成三个分量:时间(temporal)、高(height)、宽(width) ,让同一套机制能同时表达三种模态的位置。
图 7 · M-RoPE:一套坐标,三种模态
文本 · 1 维
t
t+1
t+2
t+3
位置 = (序号)
图像 · 2 维(高 × 宽)
0,0
0,1
0,2
1,0
1,1
1,2
位置 = (高, 宽)
视频 · 3 维(时间 × 高 × 宽)
每帧 = 一个 (高,宽) 平面
帧与帧之间 = 时间维递增
位置 = (时间, 高, 宽)
为什么这很重要: 因为文本、图像、视频共用同一套位置编码机制,Qwen2-VL 可以把它们自由混排在同一个序列里 ——多张图、图文交错、整段视频,模型都知道每个 token 在「时-空」里的确切位置。视频对它而言不过是「时间维 > 0 的图像」,天然统一。
一个常被忽略的细节
Qwen 系列没有 Q-Former,也没有复杂的融合层 。视觉 token 经 2×2 合并后,直接和文本 token 拼在一起、丢进 LLM,靠 LLM 自己的 self-attention 完成融合。连接器极简,复杂度被转移到了「如何表示位置」(M-RoPE)和「如何控制 token 数」(动态分辨率 + 合并)上。
Part 4 — 正面对决
逐条对照
把两者放在一起,差异就清晰了。注意:这不是「谁更先进」的排名,而是两套针对不同优先级的取舍 。LLaVA 押注简单与可复现,Qwen2-VL 押注保真与统一。
维度
LLaVA / LLaVA-1.5
Qwen2-VL
分辨率处理
强制缩放到固定 336×336固定
保留原生分辨率,任意尺寸动态
视觉 token 数
恒定 576 个
随图浮动,从几十到数千
ViT 位置编码
CLIP 自带的绝对位置编码
改造为 2D-RoPE(支持任意尺寸)
LLM 位置编码
标准 1D-RoPE
M-RoPE(时间/高/宽 三分量)
连接器
2 层 MLP
2×2 合并的 MLP(同时压缩 token)
视觉编码器
现成的 CLIP ViT-L/14,训练中冻结
自研 ~675M ViT,与 LLM 联合训练
视频支持
原生不支持(需外挂方案)
原生支持,视频=带时间维的图像
擅长场景
通用图文问答、研究基线
高清文档/表格/长截图、多图、视频、Agent
设计哲学
把世界裁剪成模型的样子 · 极简
让模型适应世界的样子 · 保真
一句话记住
LLaVA 问的是「我该怎么把图缩进我的格子」,Qwen2-VL 问的是「我该怎么长出能装下这张图的格子」。 前者把复杂度留在外部(缩放、切块),后者把复杂度吸收进架构(动态分辨率、M-RoPE)。
Part 5 — 拓宽边界
把镜头拉远:它们在版图的哪里
LLaVA 与 Qwen2-VL 不是孤立的两个点,而是两条更大演化脉络上的坐标。理解这些脉络,你就能把任何一个新出的 VLM 快速归位。这里有两条主轴特别值得记住:连接器怎么设计 ,以及分辨率怎么处理 。
主轴一:连接器的四种流派
「怎么把视觉特征接进 LLM」这件事,业界尝试过四类思路,各有取舍:
图 8 · 连接器家族:从重到轻的四种思路
① 线性 / MLP 投影
LLaVA · Qwen-VL
MLP
最简单:直接逐 token 投影。
token 数不变,保留全部信息。
② Q-Former
BLIP-2 · InstructBLIP
Query
Transformer
用少量可学习 query 抽取信息,
大幅压缩 token,但会丢细节。
③ 交叉注意力
Flamingo
x-attn
在 LLM 内部插入交叉注意力层,
让文本「回看」图像,改动较大。
④ Token 合并 / 池化
Qwen2-VL · 2×2
MLP 折叠相邻 patch,在「保信息」
与「省 token」之间折中。
从①到④,大致是「保留信息 ↔ 压缩 token」这根轴上的不同站位。LLaVA 站在①(信息全留、token 固定),Qwen2-VL 站在④(动态保真 + 适度压缩)。JD 里点名要懂的 Q-Former (②)和 C-Abstractor 都属于「压缩派」,理解了这根轴,它们就不再是孤立的名词。
主轴二:分辨率处理的三级跳
如果把「模型怎么对待图像尺寸」按时间排开,会看到一条清晰的进化路线——而 LLaVA 与 Qwen2-VL 正好是这条线上前后相邻的两代:
图 9 · 分辨率处理的演化:固定 → 切块 → 原生动态
① 固定分辨率
缩到 336²,576 token
LLaVA-1.5
② 切块 / AnyRes
大图切几块分别编码
LLaVA-NeXT · InternVL
③ 原生动态分辨率
任意尺寸,动态 token
Qwen2-VL · NaViT 启发
②其实是给①打的补丁——既然不能改尺寸,那就把大图切成几张小图。而 Qwen2-VL 的③直接从根上解决:让 ViT 原生吃任意分辨率(这思路受 Google 的 NaViT 启发)。看懂这条线,你就明白为什么说 Qwen2-VL 代表了「下一代」的方向。
再往前看一步:Qwen2.5-VL 又改了什么
如果你后面要上 7B 版本,值得知道 Qwen2.5-VL 在 2-VL 基础上的几个增量:把视频的「固定采样」升级为动态帧率(dynamic FPS) 采样、给 ViT 引入window attention 降低高分辨率下的计算量、并加入绝对时间编码 让模型对「事件发生在视频第几秒」更敏感。方向很一致——沿着「原生、统一、高效」继续走。这些都建立在你已经理解的 2-VL 三大改造之上,不会推翻它们。
Part 6 — 落到实处
这些差异,对你做后训练意味着什么
架构差异不只是知识点,它会实实在在地影响你训练时的每一个旋钮。如果你选 Qwen2-VL 做基座(这是个好选择),下面几条是你迟早会撞上的:
① token 数 = 显存,而它由你控制
因为 token 数随分辨率浮动,你在训练框架里会看到一个 MAX_PIXELS(或 min/max pixels)参数——它本质是给「一张图最多产生多少 token」设上限。调大 = 看得更清但更吃显存,调小 = 省显存但可能糊掉文档细节。这是 LLaVA 时代不存在的旋钮,因为那时 token 数是写死的 576。
② 数据里的图片尺寸会直接影响序列长度
在 LLaVA 上,每条样本的视觉部分都是 576 token,长度可预测;在 Qwen2-VL 上,一条带高清大图的样本可能瞬间吃掉几千 token。做 batch、估算 max_length、排查 OOM 时,这个差异是头号嫌疑人。
③ 想做文档 / 表格 / 视频任务,Qwen 是更顺的起点
如果你的偏好对齐任务涉及密集文字、细密图表或视频理解,Qwen2-VL 的原生高分辨率和视频支持会让你少打很多补丁。反过来,如果只是通用图文问答的研究基线,LLaVA-1.5 的简单和海量现成复现资料反而省心。
把它接回你的项目
在你的「VLM 后训练全流程」项目里,选 Qwen2-VL-2B 做基座、用 DPO/GRPO 做对齐时,这篇文章里的每个机制都会现身:配数据时你要懂 token 预算(动态分辨率),调显存时你要懂 MAX_PIXELS(2×2 合并),理解为什么它能统一处理多图时你要懂 M-RoPE。架构不是背景,它是你每天要拧的旋钮。
收束:两种哲学,一个方向
LLaVA 用极致的简单证明了「投影 + 指令微调」这条路走得通,它是整个领域的地基,也是最好的入门教材。Qwen2-VL 则把复杂度从外部(缩放、切块)吸收进架构内部(动态分辨率、M-RoPE),换来了对真实世界更高的保真度和对图、文、视频的统一处理。
它们看起来对立,其实指向同一个方向——让模型越来越贴近世界本来的样子,而不是反过来 。当你理解了「图像如何变成 token」这一个根问题,以及围绕它的两条主轴(连接器、分辨率),你就握住了读懂几乎任何一个新 VLM 的钥匙。
三句话速查
① 一切始于 patchify:图像被切成 patch、变成 token。
② LLaVA = 固定分辨率 + 固定 576 token + 极简 MLP。
③ Qwen2-VL = 动态分辨率 + 2×2 合并 + M-RoPE,原生支持图/文/视频。
延伸阅读
arXiv Qwen2-VL · Enhancing Vision-Language Model's Perception of the World at Any Resolution — 2409.12191 · arxiv.org/abs/2409.12191
arXiv CLIP · Learning Transferable Visual Models From Natural Language Supervision — 2103.00020 · arxiv.org/abs/2103.00020