视觉语言模型 · 架构详解

两种看世界
的方式

LLaVA 把图像压成固定的方格, Qwen2-VL 让图像保留自己的形状。 同一个问题——「怎么让只懂文字的语言模型看见世界」——它们给出了两种截然不同的答案。

视觉 token / 视觉通路 文本 token / 语言通路
主题 · VLM 架构原理与差异 深度 · 从零基础到能动手 配图 · 全部手绘 SVG 图解

一个大语言模型(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 = 1616 × 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,原生支持图/文/视频。

延伸阅读

arXivQwen2-VL · Enhancing Vision-Language Model's Perception of the World at Any Resolution — 2409.12191 · arxiv.org/abs/2409.12191
arXivQwen2.5-VL Technical Report — 2502.13923 · arxiv.org/abs/2502.13923
arXivLLaVA · Visual Instruction Tuning(NeurIPS'23)— 2304.08485 · arxiv.org/abs/2304.08485
arXivLLaVA-1.5 · Improved Baselines with Visual Instruction Tuning — 2310.03744 · arxiv.org/abs/2310.03744
arXivCLIP · Learning Transferable Visual Models From Natural Language Supervision — 2103.00020 · arxiv.org/abs/2103.00020
arXivViT · An Image is Worth 16x16 Words — 2010.11929 · arxiv.org/abs/2010.11929
arXivBLIP-2(Q-Former)— 2301.12597 · arxiv.org/abs/2301.12597
arXivFlamingo(交叉注意力)— 2204.14198 · arxiv.org/abs/2204.14198
arXivNaViT · Patch n' Pack: Native Resolution ViT(原生分辨率的思想来源)— 2307.06304 · arxiv.org/abs/2307.06304