打痛点 (a):怎么不用卷积、直接拿 Transformer 处理图像。
关键想法:把图像切成不重叠的小方块,每块线性嵌入成一个向量 + 位置编码, 然后丢进一个标准 Transformer 编码器——和处理文字一模一样。"patchify"从此成为所有 VLM 共享的图像 token 化原语。
用纯注意力替代了 CNN 的归纳偏置,让"图像"和"文字"第一次能用同一种积木拼。
一个大语言模型(LLM)天生只认识一串 token。它没有"眼睛"。那么,当你把一张图片 塞给 GPT-4o、Claude、Gemini,它到底"看见"了什么?这张图是怎么被翻译成 LLM 能 读的东西、又是从哪个口子喂进去的?
预设读者:会基本的高数、线性代数、机器学习(知道什么是矩阵乘法、 softmax、注意力、autoregressive 下一个 token 预测)。不会 VLM 也没关系——我们从 "一张图怎么切成方块"讲起,一路讲到 2026 年的最新模型,以及大厂王牌靠公开的 token 账单暴露出来的真实接图方式。
(1) 完全零基础:从 §1 一路读下去,前四节把整套流水线和四个痛点
讲清楚,后面每一章都在解决这四个痛点之一。
(2) 已经知道 CLIP / LLaVA:直接跳到 §10 Flamingo 和 §18 AnyRes,
那里是"图像怎么注入"和"分辨率怎么救"两个分水岭。
(3) 只关心大厂和最新:直接看 §26 大厂王牌(含 token 账单计算器)
和 §31 Frontier。
这不是单纯的论文清单,也不是只讲一个架构。每一章里:paper card 给你"这一篇是谁、解决什么、和上一篇差在哪"的综述视角;带 · 拆解 标记的 小节给你"这个机制到底怎么连线"的深度走查(形状、公式、伪代码、可拖动的 demo)。 综述与拆解并行。
先把整件事压缩成一句话。一个现代 VLM(Vision-Language Model)= 一个本来只会读文字的 LLM + 一套"把像素翻译成 LLM 词向量空间里的向量"的装置。图像不是被理解成图像,而是被 翻译成一段 LLM 读得懂的"外语 token",然后和文字 token 拼在一起,喂进 那个再普通不过的 decoder。
几乎所有 VLM 都是同一个套路:图像 → 切成小块 → 每块变成一个向量 → 把向量 搬进 LLM 的词向量空间 → 当成 token 喂给 LLM。三十多篇论文的全部分歧,都只是 在这条链上某一环"换一颗螺丝"。
这条链有三段,记住这三个名字,后面每一章都在改其中一段:
| 段 | 名字 | 它做的事 | 典型实现 |
|---|---|---|---|
| ① 眼睛 | Vision Encoder 视觉编码器 | 像素 → 一格一格的特征向量 | CLIP / SigLIP 的 ViT |
| ② 翻译 | Connector 连接器 / adapter | 视觉向量 → LLM 词向量空间 | 线性 / MLP / Q-Former / Resampler |
| ③ 大脑 | LLM Backbone 语言底座 | 把图像 token + 文字 token 一起读,自回归输出 | Vicuna / Qwen / Llama … |
这张三段图请刻在脑子里。下面所有章节,都可以问一句话定位它:"它改的是 眼睛、翻译,还是大脑读图的方式?"
LLM 的世界里,文本被切成 token。要让图像进来,第一步就是把图像也切成"token"。最主流的 切法来自 ViT(Vision Transformer):把图像切成不重叠的小方块(patch), 每个方块拍扁、线性投影成一个向量。一个 patch,就是图像的一个"单词"。
设一张 RGB 图 $X \in \mathbb{R}^{H \times W \times 3}$,patch 边长 $P$。patch 的个数是
$$ N = \frac{H}{P}\cdot\frac{W}{P} = \frac{HW}{P^2}. $$每个 patch 拍扁成 $x_p^{(i)} \in \mathbb{R}^{P^2\cdot 3}$,再用一个矩阵 $E$ 投影到维度 $d$("patch embedding"),加上位置编码:
$$ z^{(i)} = E\,x_p^{(i)} + b,\qquad E \in \mathbb{R}^{d \times (P^2\cdot 3)}. $$$N$ 这个数字是整个领域的成本中枢,请记住几个常用值:
| 编码器 | 分辨率 / patch | patch 数 N(= 图像 token 数) |
|---|---|---|
| ViT-B/16 | 224 / 16 | $14^2 = 196$ |
| CLIP ViT-L/14@336 | 336 / 14 | $24^2 = 576$ |
| SigLIP-SO400M/14@384 | ≈378 / 14 | $27^2 = 729$ |
记住这条经验法则:一张普通图 ≈ 几百个 token。一张 4K 文档如果不做任何处理, 按比例就是几万个 token——而注意力是 token 数的平方复杂度。"一张图等于一段很长的文字", 这就是后面所有麻烦的根源。先用下面的 demo 把"切块→数 token"这件事玩熟。
三段流水线里,眼睛(CLIP/SigLIP)通常是预训练好、且冻结的——它早就在 4 亿图文对上学会了"把图像放进一个和语言对齐的空间"。大脑(LLM)是预训练好的,要不要解冻 视情况。真正从零训练、连接两个世界的,是中间那个不起眼的 connector。
这就引出了 VLM 训练的经典两段式(LLaVA 确立的范式):
| 阶段 | 解冻谁 | 数据 | 目的 |
|---|---|---|---|
| Stage 1 对齐预训练 | 只训 connector(眼睛+大脑都冻) | 图-文 caption 对 | 教翻译器把视觉向量投到 LLM 词向量空间 |
| Stage 2 指令微调 | 解冻 LLM(眼睛可选) | 视觉指令对话 | 教大脑"看着图回答问题" |
损失始终是再熟悉不过的自回归交叉熵,且只在答案 token 上计算(图像 token 和提问 token 不参与预测):
$$ \mathcal{L} = -\sum_{t\in\text{answer}} \log p_\theta\big(y_t \mid y_{把上面三十多篇论文摊开看,它们解决的问题会聚成四个反复出现的痛点。 后面每张 paper card,我都会标注它在打哪个痛点。先把这四个字记牢:
视觉编码器吐出的向量,天然不在 LLM 的语义空间里。怎么把它"翻译"过去?靠对比预训练 (CLIP/SigLIP)先把眼睛拉进语言空间,再靠一个 connector + 对齐阶段把它对准 LLM。
ViT 通常是固定低分辨率(224/336)。但文档、图表、票据需要看清小字。固定分辨率一缩放, 字就糊了。怎么喂高分辨率?
每个 patch 都是一个 token,注意力是平方复杂度。高分辨率 = token 爆炸 = 算不动。怎么用 更少的 token 装下更多的图?(Resampler、Q-Former、pixel-shuffle 都在打这个。)
图像 token 从哪个口子进 LLM?两条路:前缀(prefix)——拼在输入序列最前面, 当软提示;交叉注意力(cross-attention)——在 LLM 内部插入新层,让文字去 "看"图像。前者简单、吃 context;后者不吃 context、但要改架构。
把 (a)(b)(c)(d) 这四个字母钉在墙上。从下一章起,每一篇论文都是在这张 四象限图的某个角落上"拧一颗螺丝"。
打痛点 (a):怎么不用卷积、直接拿 Transformer 处理图像。
关键想法:把图像切成不重叠的小方块,每块线性嵌入成一个向量 + 位置编码, 然后丢进一个标准 Transformer 编码器——和处理文字一模一样。"patchify"从此成为所有 VLM 共享的图像 token 化原语。
用纯注意力替代了 CNN 的归纳偏置,让"图像"和"文字"第一次能用同一种积木拼。
打痛点 (a):怎么得到一个"特征已经和语言对齐"的视觉编码器。
关键想法:双塔(图像塔 + 文字塔)对比学习。一个 batch 里有 $B$ 对真图文, 构成 $B\times B$ 的相似度矩阵,让对角线(真配对)的相似度高、其余低。监督信号来自 4 亿条 自然语言 caption,而不是固定标签集——所以学出来的视觉特征天生"会说话"。
这正是后来几乎所有 VLM 都拿冻结的 CLIP ViT 当眼睛的原因:它的输出已经站在语言这一侧了。
CLIP 的损失是一个对称的 InfoNCE。设第 $i$ 张图的归一化特征 $I_i$、第 $i$ 段文字的特征 $T_i$, 温度 $\tau$:
$$ \mathcal{L} = -\frac{1}{2B}\sum_{i}\Big[\log\frac{e^{\langle I_i,T_i\rangle/\tau}}{\sum_j e^{\langle I_i,T_j\rangle/\tau}} + \log\frac{e^{\langle I_i,T_i\rangle/\tau}}{\sum_j e^{\langle I_j,T_i\rangle/\tau}}\Big]. $$两项分别是"给定图找对的文字"和"给定文字找对的图"。每张图把自己那段文字当正例、batch 里 其余所有文字当负例。训练完,图像向量和它的描述向量在同一个球面上彼此靠近。 下面的 demo 让你直接看这个 $B\times B$ 矩阵:调高温度或噪声,对角线就从"清晰发亮"塌成 "一片模糊"——那正是对齐失败的样子。
打痛点 (a):CLIP 的 softmax 需要全 batch 归一化,把损失绑死在超大 batch 上。
关键想法:把每一对图文当成独立的二分类,用成对 sigmoid 损失, 去掉 batch 内的全局归一化。损失从此和 batch 大小解耦,小 batch 也能训得好。
SigLIP 编码器在 2024 年后大面积取代 CLIP,成为 PaliGemma、Idefics2/3、Gemma 3、SmolVLM 等的默认眼睛。
打痛点 (c):注意力是输入长度的平方,长输入算不动。
关键想法:一小撮可学习的 latent 查询去 cross-attend 那个又大又长的 输入数组,把它蒸馏进一个固定大小的瓶颈。"固定 latent 读取可变输入"这个非对称模式,正是后来 Flamingo 的 Perceiver Resampler 和 BLIP-2 的 Q-Former 的直系祖先。
第一次给出"把可变长的视觉网格压成固定 token 预算"的通用机器——这就是痛点 (c) 的标准解法之一。
这一部讲连接器家族——怎么把视觉接到一个已经训练好的 LLM 上。一开始大家追求 "尽量不动 LLM",于是分裂成两条路线:前缀(把图像 token 拼到输入最前面)和 交叉注意力(在 LLM 内部插新层)。Frozen 开了前缀这条路。
打痛点 (a)(d):一个完全冻结的 LM,到底能不能用上图像?
关键想法:只训练一个视觉编码器,让它吐出几个连续向量,当作软提示 (soft prompt)拼在冻结 LM 的输入前面,纯用 caption 的语言模型损失训练。它第一次证明: 图像可以是 LLM 词向量空间里的一段前缀,并由此解锁多模态的 in-context few-shot。
这是"前缀注入"范式 (d-prefix) 的概念种子——后来的 BLIP-2、LLaVA、几乎所有现代 VLM 都走这条路。
打痛点 (c)(d):怎么把可变分辨率、交错的图文长文档喂进一个大冻结 LM。
关键想法:两件法宝。① Perceiver Resampler 把可变的视觉网格压成固定 64 个 token;② 在冻结 LM 的层与层之间插入新的门控交叉注意力层(GATED XATTN-DENSE), 用一个初始为 0 的 tanh 门,让 LM 一开始原封不动,再慢慢"睁眼"。
和 Frozen 的前缀不同,Flamingo 把视觉深深注入 LM 内部(cross-attention 范式 d-xattn),并天然处理多图交错文档。
交叉注意力的危险在于:你往一个训练好的 LM 里插新层,一上来就可能把它搅乱。Flamingo 的解法是 给每个新层配一个可学习标量 $\alpha$,初始化为 0,乘在 $\tanh$ 里:
$$ y \leftarrow y + \tanh(\alpha_{\text{xattn}})\cdot \mathrm{CrossAttn}(q{=}y,\; kv{=}V), $$ $$ y \leftarrow y + \tanh(\alpha_{\text{ff}})\cdot \mathrm{FFW}(y). $$$\tanh(0)=0$,所以训练第一刻,这两条新支路的输出是 0,整个 LM 精确等于它原来的样子。 随着训练,门慢慢打开,视觉信息一点点渗进来。这是"在不破坏底座的前提下加新能力"的经典工程手法, 后来 Llama 3.2 Vision 的 cross-attention adapter 用的是同一招。
这是全站最该想清楚的一张对比。同样是"把图像 $H$ 给 LLM",前缀和交叉注意力是两种世界观:
| 前缀 prefix(LLaVA 路线) | 交叉注意力 cross-attn(Flamingo 路线) | |
|---|---|---|
| 图像在哪 | 拼进输入序列:$[h_1..h_M, e_1..e_T]$ | 当 KV,插在 LLM 层间,文字当 Q |
| 吃不吃 context | 吃,每个图像 token 占一格序列长度 | 不吃,图像 token 不占序列预算 |
| 动不动 LLM | 通常要微调 LLM 才读得懂 | LLM 可全程冻结(门控让新层初始为恒等) |
| 多图 | token 线性叠加,长度爆炸 | 天然支持大量交错图像 |
| 带宽 | 高,文字能逐 token 直接看图 | 受 cross-attn 层数瓶颈限制 |
2023 年后,前缀路线赢了主流(简单、能复用任意 LLM);但交叉注意力在"多图、长视频、 想冻结底座"的场景里一直活着。下面的 demo 把这两条路画成同一个 Transformer 栈,自己切换看看。
打痛点 (a)(c):怎么用现成的冻结编码器 + 冻结 LLM,便宜地搭一座桥。
关键想法:一个轻量的 Q-Former——32 个可学习查询 token 去 cross-attend 冻结 ViT 的特征,输出 32 个向量、线性投影后当前缀喂给冻结 LLM。 两段训练:先做视觉-语言表示学习,再接到 LLM 做生成学习。
相比 Flamingo,BLIP-2 把编码器和 LLM 双双冻结,只训那个小 Q-Former,且回到前缀注入。
Q-Former 是"connector 动物园"里最精巧的一只。它的核心是一组固定数量 $K{=}32$ 的查询向量 $Q\in\mathbb{R}^{K\times d}$,不管输入图像有多少个 patch($N$ 可能是 576、729、上千), 这些查询 cross-attend 之后永远吐出 32 个向量:
$$ \tilde Q = \mathrm{CrossAttn}(q{=}Q,\; k,v{=}V) \;\Rightarrow\; H \in \mathbb{R}^{32 \times d_l}. $$也就是说,无论图多大,进 LLM 的永远只有 32 个图像 token。这是对痛点 (c) 最激进的 压缩。代价是:32 个 token 的带宽有限,细粒度任务(OCR、数小目标)会吃亏——这也是为什么 2024 年后 主流从"重压缩 Q-Former"转向了"轻压缩 MLP + 高分辨率切图"。下面 Demo 4 会把这几种 connector 并排比。
打痛点 (a):用最小的训练量,逼近 GPT-4 式的图文对话。
关键想法:冻结 BLIP-2 的 ViT+Q-Former、冻结 Vicuna,只训中间一层线性投影, 再用一小批高质量对话数据微调。证明"全冻 + 一层线性 + 少量精调"就能聊起来。
把 BLIP-2 的两段重训简化到只剩一层线性 + 短微调。
打痛点 (a):抽取的视觉特征应该随"当前问的是什么"而变。
关键想法:BLIP-2 的骨架,但把指令文本也喂给 Q-Former,让 32 个查询 抽取"和指令相关"的视觉特征;在 26 个数据集上做指令微调。
connector 从"和指令无关"变成"指令感知"——同一张图,问颜色和问数量,抽出来的 token 不一样。
打痛点 (a)(d):能不能用最朴素的连接器 + 好数据,开源地做出强 VLM。
关键想法:冻结 CLIP ViT-L/14 的特征 → 一个线性投影 → 当前缀喂给 Vicuna。 真正的创新是数据:用 GPT-4 合成视觉指令对话来做 Stage 2 微调。机制极简,效果惊人。
把 BLIP-2/MiniGPT-4 的 Q-Former 整个扔掉,换成一层线性映射;并首创"合成视觉指令微调"。
LLaVA 的 forward 是整套范式里最干净的样板,背下来你就懂了 80% 的现代 VLM。注意第 4 步:图像 token
被"散播"进文本序列里 <image> 占位符的位置,之后就是一个普通 decoder。
# 形状:B=batch, N=图像 patch 数, T=文本长度
# d_v=视觉维度, d_l=LLM 隐藏维度, V_vocab=词表大小
def llava_forward(image, input_ids, image_token_pos):
# 1. 视觉编码器(冻结):图像 -> patch 特征,丢掉 [CLS]
vis_feats = vision_encoder(image) # (B, N, d_v)
# 2. Connector:把视觉特征投到 LLM 的词向量空间
img_embeds = projector(vis_feats) # (B, N, d_l) 线性 / 2 层 MLP
# 3. 文本走 LLM 自己的 token embedding 表
txt_embeds = llm.embed_tokens(input_ids) # (B, T, d_l)
# 4. 把图像 token 散播进 占位符的位置 —— 拼成一条序列
inputs_embeds = scatter_image_tokens( # (B, N + T, d_l)
txt_embeds, img_embeds, image_token_pos)
# 5. 一个再普通不过的 decoder-only LLM,整条序列照常跑
hidden = llm.transformer(inputs_embeds) # (B, N + T, d_l)
# 6. LM head -> 下一个 token 的 logits
logits = llm.lm_head(hidden) # (B, N + T, V_vocab)
return logits
# Loss = 只在答案 token 上的交叉熵(图像/提问位置被 mask 掉)
把这段代码和 §11 的 Q-Former、§9 的 Frozen 对照:它们的差别只在第 2 步那一个函数 (projector 是什么)。这就是为什么我说"全领域都在一条链上换螺丝"。下面 Demo 4 就是把第 2 步的几种 实现并排放,看 token 怎么变形。
打痛点 (a)(b):朴素 LLaVA 还能怎么便宜地变强。
关键想法:把线性投影换成两层 MLP(GELU),分辨率提到 336²,再加 VQA / 学术数据。一个又便宜又强的基线就这么立住了。
connector 从一层线性升级为两层 MLP;这之后"MLP connector"成了开源 VLM 的事实默认。
打痛点 (c):用一个抽象器把视觉特征压成固定 token。
关键想法:一个 Perceiver 风格的视觉抽象器把编码器特征压成一组可学习 token 当前缀;两段训练(先视觉预训练,再 LoRA 调语言)。
用 resampler 抽象器代替 LLaVA 的线性投影——是"轻压缩 vs 重压缩"路线之争的一个早期样本。
打痛点 (c)(d):压缩 token 时,2D 空间布局丢了,grounding 就废了。
关键想法:一个单层 cross-attention 的"位置感知 VL adapter",用可学习查询把 ViT 特征压到 256 token,并显式加上 2D 绝对位置编码保住布局;三段训练,带 bbox/grounding 数据。
在 resampler 压缩的同时,把"哪个 patch 在图的哪里"重新注入——为后来 M-RoPE 埋了伏笔。
打痛点 (d):交叉注意力 + 交错图文这条 Flamingo 路线,缺一个开放的数据 + 权重证据。
关键想法:OBELICS 是 1.41 亿文档的开放交错图文网络语料;IDEFICS(9B/80B)是它上面训练的 开源 Flamingo 复刻(Perceiver resampler + 门控交叉注意力)。
把闭源 Flamingo 的"交错 + cross-attn"配方完整开源,证明它可复现。
打痛点 (d):最朴素的"一个编码器 + 一个文本 decoder"能走多远。
关键想法:图像编码器的 token 当前缀喂文本 decoder,端到端训练做 captioning。极简生成式 VLM, 没有冻结 LLM 的花活。
不借冻结大 LLM,自己从头训一个小的——是"适配预训练 LLM"路线的对照组。
打痛点 (a)(d):与其适配冻结 LM,不如让 LM 一开始就多模态地长大。
关键想法:在交错图文上从头训练一个 MLLM,视觉特征作为 token 内联进序列; Kosmos-2 用 bbox 位置 token 加入 grounding(GRIT 数据)。
LM 本身被多模态地训练,而不是事后被适配——是 early-fusion / 原生多模态的早期信号。
打痛点 (d):机器人要把图像、状态、传感器都塞进一个 LM 推理。
关键想法:把 ViT(及其他传感器)embedding 当作"多模态 token"内联进 PaLM 的 输入序列,用于具身推理,规模高达 562B。
把"任意模态 → 投进 LM token 空间 → 和文字交错"推到极致,连机器人状态都当 token。
打痛点 (b):把视觉塔和文本塔一起放大,分辨率和多语言一起上。
关键想法:encoder-decoder 架构,一个大 ViT 把图像 token 喂给 mT5 式文本 enc-dec, 联合放大、多语言。
不走 decoder-only,坚持经典 enc-dec 文本骨架,并把视觉塔激进放大。
第二、三部把"对齐"和"注入"讲完了,但痛点 (b)(c) 还杵在那:固定 336² 看不清小字。这一部就是 和分辨率搏斗的历史,分两条路——切图(把大图剁成小块)和 原生动态分辨率(让编码器直接吃任意尺寸)。LLaVA-NeXT 开了切图这条路。
打痛点 (b):固定 336² 丢失细节 / OCR 读不了小字。
关键想法:AnyRes——把高分图按动态网格切成若干个 336² 的子图(2×2、1×2、 4×1……),每块单独过编码器,再把所有子图 token 加上一张缩小的全局缩略图拼成前缀。
相比 LLaVA-1.5,用约 4× 的像素(靠切图),代价是图像 token 预算大涨——典型的"花 (c) 买 (b)"。
AnyRes 的算账很直白:原图选一个最接近的网格 $g_r\times g_c$,每个格子缩放到 336²、各自产生 576 个 token。 总图像 token ≈
$$ \text{tokens} \approx \underbrace{g_r\,g_c \times 576}_{\text{切片细节}} \;+\; \underbrace{576}_{\text{全局缩略图}}. $$一张 2×2 切的图就是 $4\times576 + 576 = 2880$ 个 token——是单图的 5 倍。那张全局缩略图是关键:切片只看见 局部,缩略图负责告诉 LLM"整张图长什么样、各块怎么拼",否则模型会"只见树木不见森林"。 下面 Demo 5 让你拖分辨率,亲眼看切片数、token 数怎么涨,以及"能不能读清这行小字"怎么随之翻转。
打痛点 (b)(c):切图救了分辨率,但 token 又太多,怎么省回来。
关键想法:动态切片(448² 子图 + 缩略图)解决分辨率;同时用 pixel-unshuffle 把每个子图的 token 压到 256(4× 压缩),把空间分辨率折叠进通道维。
在 AnyRes 切图之上叠一层 pixel-shuffle 压缩,让"高分辨率"和"省 token"同时成立。
pixel-shuffle 是最优雅的省 token 技巧,没有任何可学习参数,就是一次 reshape。设视觉网格 $\sqrt N \times \sqrt N \times d_v$,取缩放 $s=\tfrac12$:把每个 $2\times2$ 的 patch 邻域叠进通道:
$$ \mathbb{R}^{\sqrt N \times \sqrt N \times d_v} \;\longrightarrow\; \mathbb{R}^{\,\frac{\sqrt N}{2} \times \frac{\sqrt N}{2} \times 4d_v}. $$token 数变成 $1/4$,每个 token 的通道数变成 $4\times$——信息没丢,只是从"多而薄"重排成"少而厚",再用一个 MLP 投到 $d_l$。具体地,一个 448² 子图(ViT/14 → $32\times32=1024$ patch)压成 $16\times16=256$ token。 1024 → 256,这就是 InternVL 系列能又高清又省的秘密。Demo 4 里选 "pixel-shuffle" 就能看这次折叠。
打痛点 (b):为什么非得把每张图都强行缩到同一个方块。
关键想法:Patch n' Pack——把不同分辨率、不同长宽比图像的 patch 序列像 NLP 那样打包进一个 batch(带 attention mask 隔开),让 ViT 原生吃任意分辨率,不再裁切缩放。
从"切图来迁就固定编码器"转向"让编码器本身适应任意尺寸"——这是另一条解 (b) 的路。
打痛点 (b)(c):原生动态分辨率下,怎么让 LLM 知道每个 patch 的 2D 位置。
关键想法:Naive Dynamic Resolution(可变 patch 数,不切片)+ M-RoPE(多模态旋转位置编码,把位置拆成时间/高/宽三组),MLP 把相邻 2×2 patch 压成一个 token。
把 NaViT 的原生分辨率落进生产级 VLM,并用 M-RoPE 把 2D(图)/3D(视频)位置一次性解决。
普通 RoPE 只编码 1D 位置。Qwen2-VL 的 M-RoPE 把旋转通道分成三组,各配一个位置索引: 时间 $t$、高 $h$、宽 $w$。位于第 $t$ 帧、网格 $(h,w)$ 的 patch,旋转角度是
$$ \mathrm{RoPE}_t(\text{组}_1)\;\oplus\;\mathrm{RoPE}_h(\text{组}_2)\;\oplus\;\mathrm{RoPE}_w(\text{组}_3). $$妙处在于退化:对一张静态图,$t$ 不变、$h,w$ 扫过网格;对纯文本,$t,h,w$ 三个索引collapse 成同一个值, M-RoPE 精确退回普通 1D RoPE。于是一套位置方案,文字(1D)、图像(2D)、视频(3D)通吃——这是 2024 年后原生分辨率模型的标准件。
打痛点 (b)(c):现成 CLIP 不支持原生分辨率,那就自己训一个。
关键想法:一个 4 亿参数 ViT 从头训练,带 RoPE-2D、原生分辨率与长宽比,靠 块对角注意力把多图打包进一条序列。
不再复用 CLIP/SigLIP,而是为 VLM 量身从零训一个原生分辨率视觉塔。
打痛点 (b)(c):高分辨率和省成本怎么兼得。
关键想法:"先放大再压缩"(scale-then-compress)——先把图缩放到原生分辨率 (1–12× 切片),再把 token 压 2.4×,训练/推理双双提效。
把"提分辨率"和"压 token"显式拆成先后两步,作为一个可调的效率旋钮。
前面所有模型都有一只独立的眼睛(CLIP/SigLIP)。这一部的叛逆者问:能不能没有编码器,让 patch 直接当 token? 甚至——让图像和文字共用一个词表、一个 softmax,从而既能读图又能生成图?
打痛点 (b)(d):独立编码器既限制分辨率,又是个累赘。能不能没有它。
关键想法:无编码器——原始图像 patch 直接线性投影进 decoder 的第一层,和文字 token 在序列里按光栅顺序交错,用 image-newline 标记换行;底座就是一个朴素 decoder-only Transformer。
没有 CLIP、没有 resampler——patch 是一等公民 token(连续型 early-fusion)。
Fuyu 把 §2 的 patch embedding 直接当成了入口:一个 $P\times P$ 的原始 patch 拍扁成 $P^2\cdot3$ 维, 乘一个矩阵 $W_{\text{in}}$ 就成了第一层的输入向量——绕过了整个视觉编码器,也绕过了 token embedding 查表:
$$ \text{patch}\in\mathbb{R}^{P^2\cdot 3} \xrightarrow{\,W_{\text{in}}\,} \mathbb{R}^{d_l} \;\hookrightarrow\; \text{decoder 第 1 层}. $$好处:任意分辨率天然支持(patch 多少都行),架构极简。代价:丢掉了 CLIP 几亿图文对预训练攒下的语义先验, 得让那个 decoder 自己从头学会"看"。"省掉编码器"省的是结构,赔的是先验——这笔账要不要划算, 正是 2025 年 encoder-free 研究的核心议题(见 §25)。
打痛点 (d):要一个既能读图、又能生成图的统一模型。
关键想法:early fusion——用 VQ tokenizer 把图像变成离散 token (取自一个共享 codebook),图像 token 和文字 token 进同一个 Transformer、共用一个词表,完全自回归。
和 Fuyu 不同,图像是离散 VQ token(不是连续投影),因此模型能像吐文字一样吐出图像。
Chameleon 用一个 VQGAN 式编码器把 $512\times512$ 图压成一格格 latent,每格吸附到一个大小 8192 的 codebook 里最近的条目,得到 1024 个离散 image token。这些 ID 直接并进文本 BPE 词表(合并词表 ≈ 65536), 和文字 token 一视同仁,一个 softmax 通吃。把这一部三种接图方式并排:
| 编码器+connector(主流) | Fuyu(连续 early-fusion) | Chameleon(离散 early-fusion) | |
|---|---|---|---|
| 图像表示 | 连续向量 | 连续向量 | 离散 token(codebook ID) |
| 有没有编码器 | 有(CLIP/SigLIP,含语义先验) | 没有 | 有 VQ tokenizer(无语义先验) |
| 能不能生成图 | 不能(向量没法采样) | 不能 | 能(像采样文字一样采样 image token) |
| 软肋 | 多一个编码器 + 对齐训练 | 丢语义先验 | VQ 重建有损,图里的字尤其糟 |
打痛点 (d):理解和生成能不能用同一个最朴素的目标。
关键想法:纯离散视觉 token 上的下一个 token 预测,一个 Transformer,不要 diffusion、不要 CLIP,理解和生成都靠它。
把 Chameleon 的离散路线推到极简,证明 next-token 一个目标足以横跨理解与生成。
打痛点 (d):离散 VQ token 损图像质量,能不能让图保持连续。
关键想法:一个 Transformer 同时背两个损失——文字用下一个 token 预测、 图像用连续扩散损失。图像保持连续,不经过有损 VQ。
相比 Chameleon/Emu3 的"全离散",Transfusion 把扩散塞进同一个骨架,保住图像连续性。
打痛点 (a)(d):理解要语义、生成要细节,一种视觉表示伺候不了两边。
关键想法:解耦视觉编码——理解走 SigLIP,生成走 VQ tokenizer,两条路共享同一个 LLM 骨架,各取所需。
不强求一种表示通吃,而是按任务分两条视觉通路——化解了"理解 vs 生成"的表示冲突。
打痛点 (a):没有编码器的模型,怎么补回 CLIP 的语义先验。
关键想法:恰当的模态分解,仅用 1 亿公开数据,就超过此前所有 encoder-free 模型、并逼近同规模的 encoder-based 同行(注意:是"逼近",不是"超越")。
把 Fuyu 式 encoder-free 从"能跑"推到"接近主流",但还没追平 2025 的 encoder-based 领头羊。
打痛点 (d):单个 Transformer 直接吃原始像素,能不能和模块化 MLLM 打平。
关键想法:一个 Transformer,原始像素 + mix-attention + 多模态位置编码;规模上去后 与模块化 MLLM 相当,且去掉 ViT 反而提升了可扩展性和稠密视觉表征。
给出"去掉视觉塔反而更好扩展"的证据,是 encoder-free 路线 2025 的有力一票。
打痛点 (d):开源统一模型能不能同时理解、生成、编辑。
关键想法:Mixture-of-Transformer-Experts,7B,统一理解 + 生成 + 编辑, 报告称胜过 Janus-Pro-7B 和 SD3-medium。
把统一模型从"能做"推到"在开源里领先",是当前开源 unified 的前沿。
OpenAI、Anthropic、Google 都不公开它们王牌模型的视觉架构。但它们都公开了一件事: 一张图按多少 token 计费。这条公开账单,是它们"怎么把图变成 token"的部署级铁证—— 比任何论文都更接近真实系统。我们就用账单倒推机制,并在 Demo 6 里把四家并排算给你看。
下面四节里,token 计费公式来自各家官方文档(2026-05 核对),是硬事实;而"架构"部分, OpenAI / Anthropic 几乎没有公开,凡是推断我都会标明。Meta 的 Llama 是开源的,所以它的架构最透明、 反而不公布 token 公式(你自己跑、成本是算力不是账单)。
打痛点 (b)(c):用一套计费暴露出"高分辨率怎么切、怎么收钱"。
公开的是计费,不是架构。OpenAI 称 GPT-4o "原生多模态/omni",但不公布编码器与注入方式。 它的 token 账反而泄露了机制:分块(tile)计费,正是 AnyRes 思路的部署形态。
两代用了两套账:4o 系是"tile 制",GPT-5 系换成"patch 制 + 上限"。
GPT-4o / GPT-4.1(tile 制,high detail):先把图缩进 2048×2048,再让短边=768,然后数 512×512 的块:
$$ \text{tokens} = 85 + 170 \times \big(\text{512² 块数}\big). $$例:1024×1024 → 4 块 → $85 + 170\times4 = 765$ token。注意 GPT-4o-mini 用同样的几何、但 base=2833、每块=5667——mini 的"便宜"是单价便宜,token 数反而被放大。GPT-5 / GPT-4.1-mini/nano 改用 patch 制:$\lceil w/32\rceil\times\lceil h/32\rceil$ 个 32×32 patch,上限 1536, 再乘模型系数(4.1-mini ×1.62,4.1-nano ×2.46)。
GPT-5 的具体 patch 倍率官方文档页未单列;展示前请对一遍 OpenAI 的在线 tokenizer 计算器。
打痛点 (b)(c):用最简单的一条公式,决定一张图值多少 token。
Anthropic 公开得最少——没有编码器、patch 大小、注入方式的任何细节。唯一的窗口是文档里
那句话:"一张图大约用 width × height / 750 个 token。"
相比 OpenAI 的分块账,Claude 是一条连续的"面积 / 750"——更像原生分辨率而非固定切块。
超大图会先等比缩放到上限。关键的"模型分档"值得记(Demo 6 会按模型切换):
| 模型档 | 长边上限 | token 上限 |
|---|---|---|
| 多数 Claude(3.x / Sonnet 4.x) | 1568 px(≈1.15 MP) | 1568 |
| Claude Opus 4.7 / 4.8(高清档) | 2576 px | 4784(约 3×) |
文档给的例子:200×200 → ≈54 token;1000×1000 → ≈1334;1092×1092 → 1568(撞上限)。Anthropic 还提到图像会被 padding 到 28 的倍数——这个 28 几乎肯定暗示底层 patch/grid 是 14 或 28 的整数倍,是少数能从 账单"反推架构"的线索。
打痛点 (b)(c)(d):原生多模态训练下,图像 token 怎么定量。
Google 公开了立场和数字、但不公开内部。它强调 Gemini "从头就是多模态"——文本/图/视频/音频 交错预训练;而"258 token 一块"就是这条流水线的公开产物。
和 Claude 的连续面积制不同,Gemini 是固定块制:小图一口价、大图按 768 块各 258。
规则:两边都 ≤384 px 的小图 = 固定 258 token;更大的图切成 768×768 的块,每块 258 token。
例:960×540 → 6 块 → $6\times258 = 1548$ token。视频按每秒 263 token、音频每秒 32 token
("1 fps、每帧 258"是旧说法,现行文档是 263/秒)。Gemini 3 还加了 media_resolution 旋钮让你手调每图/帧的 token 配额。
打痛点 (d):想加视觉,又不想动坏已经很强的纯文本能力。
关键想法:一串交叉注意力层把图像编码器表示喂进语言模型;训练时更新编码器, 但刻意不动语言模型参数,保住全部文本能力——堪称 Flamingo 路线的工业落地。
这是 2024 大厂里少见的 cross-attention(晚融合)样本,目的就是"纯文本能力零损"。
打痛点 (d):晚融合的天花板,逼着转向原生多模态。
关键想法:转向 early fusion——文本 + 视觉 token 在一个统一骨架里联合预训练; MetaCLIP 系编码器;MoE(Scout 17B激活/16专家/109B 总;Maverick 17B激活/128专家/400B 总)。
从 3.2 的交叉注意力晚融合,整体掉头到 early-fusion + MoE 的原生多模态——和 Llama 4 内部细节属 blog 级,标 mustard。
把 2025–2026 的开源 SOTA 摊开,会看到一个明显的重心:原生/动态分辨率 ViT(SigLIP 或从头训的 NaViT 式)+ MLP / pixel-shuffle 连接器(约 4× 压缩)+ 前缀注入 + 2D/M-RoPE。Qwen、InternVL、Kimi、Pixtral、 SmolVLM、NVILA 全部聚在这个中心。但仍有分歧:Gemma 3 守着固定分辨率 SigLIP + 切图;Eagle 用多编码器; Ovis 用结构化嵌入表;Llama 4 / InternVL3 走 early-fusion 原生预训练。
关键想法:2.5-VL 从头训带窗口注意力的 ViT(多数层窗口、少数层全局)提效,M-RoPE 对齐绝对时间做视频;Qwen3-VL 加 interleaved-MRoPE 和 DeepStack(注入 ViT 多层特征而非只取最后一层),256K 原生上下文,含 MoE 版。
把"原生分辨率 + M-RoPE"继续推进到多层特征注入与超长上下文。Qwen3-VL 编码器身份属报告级,标 mustard。
关键想法:InternVL3 的招牌是原生多模态预训练——多模态与文本在一个预训练阶段联合学,而非把视觉嫁接到冻结 LLM 上;3.5 加 Visual Resolution Router 按 token 动态选分辨率(约 4× 推理提速)。
把 LLaVA 的"先训 LLM 再接视觉"翻转成"一起从头训",并让分辨率成为逐 token 可路由的变量。
关键想法:DeepSeek-VL2 = MoE LLM(DeepSeekMoE+MLA)+ 动态切片(384² + 缩略图);Kimi-VL = MoonViT(NaViT 式 patch 打包,不切子图)+ 2 层 MLP + Moonlight MoE(16B 总/2.8B 激活),128K 上下文。
把"动态分辨率 + 稀疏 MoE 底座"组合起来,在激活参数很小的前提下冲 SOTA。
关键想法:Molmo 用常规 CLIP→MLP→pooling,卖点是完全开放的数据(PixMo,含 2D pointing),不蒸馏闭源模型;SmolVLM2 发现小模型该用更激进的 pixel-shuffle(压缩比 r=3–4、最高 9×),把每 token 像素推到约 4096。
一个证明"开放数据也能强",一个量化了"模型越小、该压得越狠"的规律。
关键想法:Eagle 2.5 用 多视觉编码器混合(SigLIP+ConvNeXt 并行编码,通道拼接)冲长上下文;Ovis2.5 用结构化视觉嵌入表让视觉 token 像文字一样查表产生;Phi-4-multimodal 用 Mixture-of-LoRAs(冻结底座 + 视觉/音频各一个 LoRA);Gemma 3 反潮流,守着固定 896² 冻结 SigLIP(256 token)+ Pan&Scan 切图。
四个样本说明 2025 的接图方式仍在多元竞争:多编码器、结构化嵌入、LoRA 路由、固定分辨率守成,各有各的活法。
① 收敛了吗?部分收敛:默认配方是"原生动态分辨率 + SigLIP/NaViT 式编码器 + MLP/pixel-shuffle +
前缀注入 + 2D-RoPE",但编码器策略、融合深度、是否做生成仍分歧很大。
② encoder-free 追平了吗?还没。EVEv2、SAIL 在同等规模/数据下逼近主流,但没有哪个 encoder-free
模型在 2025 明确压过 Qwen2.5-VL / InternVL3 这档。是有前途的研究方向,不是生产默认。
③ 统一理解+生成怎样?活跃且在成熟:离散 AR(Emu3)、AR+扩散(Transfusion/BAGEL)、双编码器解耦
(Janus-Pro)三条路并行;但最强的"纯理解"仍由 Qwen3-VL/InternVL3.5 把持,统一仍要交一点"理解税",且在缩小。
把图接进 LLM 这件事,远没到收工。几个还敞着的口子:
把图像接进 LLM,本质只有两个动作:(a) 把像素翻译成 LLM 词向量空间里的 token——靠 CLIP/SigLIP 对齐 + 一个 connector(线性 / MLP / Q-Former / Resampler / pixel-shuffle);(b) 决定这些 token 从哪进、 花多少——前缀还是交叉注意力、固定分辨率还是原生动态、要不要切图。从 Frozen 到 GPT-4o,所有模型都只是在 这两个动作上换螺丝;而大厂的 token 账单,就是这两个动作留在世界上的、谁都能看见的指纹。
| 术语 | 解释 |
|---|---|
| patch / patchify | 把图像切成不重叠的 P×P 小方块;每块拍扁投影成一个向量(图像的"单词")。 |
| ViT | Vision Transformer,用 patch + Transformer 处理图像,是几乎所有视觉编码器的骨架。 |
| CLIP / SigLIP | 对比学习训练的双塔模型,产出"和语言对齐"的视觉编码器;VLM 最常用的"眼睛"。 |
| connector / adapter | 把视觉特征投到 LLM 词向量空间的装置:线性 / MLP / Q-Former / Resampler / pixel-shuffle。 |
| Q-Former | BLIP-2 的连接器,用 32 个可学习查询把任意多 patch 压成固定 32 个 token。 |
| Perceiver Resampler | Flamingo 的连接器,用固定 latent 查询把可变视觉网格压成固定(如 64)token。 |
| pixel-shuffle | 无参数 reshape,把 2×2 patch 邻域折进通道,token 数 ÷4、通道 ×4。 |
| 前缀注入 prefix | 把图像 token 拼到输入序列最前面当软提示;简单、吃 context(LLaVA 路线)。 |
| 交叉注意力 cross-attn | 在 LLM 层间插新层,图像当 KV、文字当 Q;不吃 context、可冻结 LLM(Flamingo 路线)。 |
| 门控 gating | 新插入层乘一个初始为 0 的 tanh 门,保证训练初始 LLM 原封不动。 |
| AnyRes / 切图 | 把高分图切成多个固定尺寸子图分别编码,再配一张全局缩略图;用 token 换分辨率。 |
| 原生动态分辨率 | 让编码器直接吃任意尺寸(NaViT 的 patch 打包、Qwen2-VL 的 dynamic resolution)。 |
| M-RoPE | 把旋转位置编码拆成时间/高/宽三组,让一套方案通吃文字(1D)/图(2D)/视频(3D)。 |
| early fusion | 图像和文字 token 在一个骨架里从头联合训练(Chameleon / Llama 4),而非事后适配。 |
| encoder-free | 不要独立视觉编码器,原始 patch 直接进 decoder(Fuyu / EVE / SAIL)。 |
| VQ token | 把图像离散化成 codebook ID(Chameleon),从而能像吐文字一样"吐"图像。 |
不是按年份,是按"理解链条"排的。先建立流水线直觉,再看两个分水岭,最后扫前沿。