语言模型的世界里只有一种东西:token。它不知道什么是像素、什么是波形、什么是帧。 所以「让模型看图」这件事,本质上只有一个问题要回答: 怎么把一张图,塞进一条 token 序列里?
上一章《一套机制,四种模态》核对了一件事:换模态时,注意力、扩散、残差这些零件都不用换。 它停在那里,没回答一个接口问题:怎么把一个已经训好的语言模型接到图像上? 阶段 2 的 ViT 先证明了一件事——图片可以切成方块、当成一句话来处理; 但 ViT 解决的是「怎么让 Transformer 看懂图」,不是「怎么让语言模型看懂图」。
| 模态 | 原始形态 | 和文本的根本差别 |
|---|---|---|
| 文本 | 一串离散符号 | 天生就是 token,直接查表就能变成向量 |
| 图像 | 一大块连续的像素值 | 没有「词」这种天然单位。切多细、切多大,都是人为决定的 |
| 音频 | 一维的连续波形 | 每秒几万个采样点,比文本密集好几个数量级 |
| 视频 | 图像序列 + 时间 | 在图像的基础上再多一个维度,token 数直接爆炸 |
文本和图像之间没有通用货币。要么造一种(把图变成 token), 要么开一条专用通道(让注意力直接连到视觉特征上)。 所有多模态架构的差别,就是在这两条路之间的不同取舍。
像一个只会中文的翻译,突然要处理一份法文合同。
方案一:先把法文翻译成中文,再交给他(把图变成 token)。
方案二:给他配一个懂法文的助手,坐在旁边随时回答他的问题(交叉注意力)。
前者的上限取决于翻译质量,后者更灵活但更复杂。
这个类比管到「谁在中间牵线」为止:现实里的助手能和翻译来回商量,
交叉注意力的「助手」只会在每一层被动看一眼图的特征,不参与推理。
互动 · 同样一段时间,各模态吃掉多少
三条路线的差别只有一处:图和语言模型之间用什么连。 「双塔」指图和文各走一个独立编码器;「投影」指把视觉特征变成 token。
三条路线:图和语言模型之间用什么连
| 比什么 | 双塔对比 | 交叉注意力 | 投影成 token 序列 |
|---|---|---|---|
| 代表 | CLIP | Flamingo | LLaVA、Qwen-VL |
| 怎么接 | 图像和文本各自编码,最后比相似度 | 在语言模型层间插入对该图像特征的注意力 | 把图像特征投影成若干 token,直接拼进文本序列 |
| 能生成吗 | 不能。它只能算「像不像」 | 能 | 能 |
| 改造语言模型 | 完全不用改 | 要改每一层的结构 | 完全不用改 |
| 今天 | 所有向量检索和「给个名字就能认」(零样本分类)的地基 | 少数模型 | 绝对主流 |
「投影成 token」赢在什么都没改:语言模型仍然是一个纯粹的语言模型,它看到的只是一条更长的 token 序列, 只不过其中有一段来自图片。所有为语言模型做的优化,一行都不用动——把算过的键值缓存下来(KV cache)、 先用小模型猜几个 token 再让大模型验(投机解码)、批处理、上下文管理,全部照旧。 工程上,「不改动已有系统」几乎总是赢。
这一章最实在的一个数,就是上下文还剩多少。 语言模型只有一个固定的「上下文窗口」,里面装着系统提示、聊天记录、和图像。 图像是里面最占地方的那种东西。 所以真正要算的问题只有一个:把文本放进去之后,这点预算还够放几张图? 下面这张图把它画出来。
互动 · 还能塞进几张图
公式卡 · 还能装几张图,就看这一条式子
B 是整个窗口(那条整条的预算),T 是先被文本吃掉的那一小块,
N 是每张图占的位置,K 就是算出来的「还能装几张」。
把分辨率从 224 拖到 2048,N 会涨几十倍,K 就贴着地面掉下去——
这就是为什么多模态应用里「传低分辨率」不是抠门,是保命。
像一个只有固定大小的行李箱:先塞进去必需品(文字),
剩下的空间全看你怎么卷衣服(图像分辨率)。
把一张图的分辨率翻倍,它占的地方就变成 4 倍——
这就是那条曲线的全部来源:不是「稍微占多一点」,是平方级地占。
这是多模态最容易被低估的成本。下面所有数字都是实时算的—— 改变分辨率、开关 tile 切分,看 token 账本怎么变。
互动 · 视觉 token 账本(真实的切块与计数)
把鼠标移到下面公式里的 H 上——上面那个「输入图像边长」滑块会亮起来。
H 就是你能拖的那条边长;P′ 是一个 token 覆盖的边长(patch 14 × 2×2 合并 = 28,图会先缩放到 28 的整数倍)。
上面那块读数里的数字,就是这条式子现算出来的。
一句 20 字的提问大约是 25 个 token。
一张 1024×1024 的图,单图一次编码约 1,369 个视觉 token;开动态分辨率切成 9 个 tile 则是 2,560 个。
按每句约 25 token 折算,一张图 ≈ 55 句话(切 tile 的方案 ≈ 100 句)。
所以多模态应用里,「少放几张图」「传低分辨率」不是抠门,而是
直接决定你的上下文能装多少轮对话。
视觉
一个常被忽略的细节:视觉编码器通常是冻着的。
很多多模态模型从头到尾都不训练视觉
互动 · 三步各训练了多少参数
提高分辨率能看清更多细节,但视觉 token 数按平方增长。 这一节把成本这笔账当场算出来。
互动 · 拖分辨率,看 token 成本怎么涨
面板里那个「能看清的最小字号 ≈ 31 px」是一条经验法则,不是精确结论:
一个字符要横跨约 2.2 个 patch(每个 patch 14 个原图像素)才可能被稳定识别,2.2×14≈31。
这个 2.2 是经验值:一个字符至少要覆盖约 2 个 patch 才不会被切碎,具体取值随字体而变,这里取 2.2。
它是常数,不随你拖的分辨率变:动态分辨率切 tile 时不缩放原图,一个 patch 永远覆盖 14 个原图像素,
所以能不能读只取决于字在原图里有多高。这一点取决于字体、对比度、语言,
以及视觉
所以别把它当公式用,把它当一个提醒:调低分辨率省 token 时,你付出的代价可能不是「稍微糊一点」,
而是「那行小字直接消失了」——而且你从输出里看不出来它消失过。
音频、视频怎么切、各要多少 token,上一章《一套机制,四种模态》已经并排算过 (那张对照表)——这一章只管视觉。 视觉自己的扩展是文档:整章当高分辨率图喂进去(而不是先用 OCR 把字抠成文本), 一章 A4 大约 1000~3000 个 token。
| 模型 | 路线 | 关键贡献 |
|---|---|---|
| CLIP 2021 | 双塔对比 | 4 亿对图文对比学习,第一次让「零样本分类」成立——给个类名就能认,不需要该类样本。
它的图像 |
| Flamingo 2022 | 交叉注意力 | 在冻结的语言模型层间插入「看一眼图」的注意力层。证明了不改语言模型主体也能做多模态 |
| BLIP-2 2023 | 轻量桥接 | 用几十个可学习 query(专门去图里「捞」信息的向量)的 Q-Former 把图压成固定长度: 视觉 token 从「按分辨率」变成「固定 32 个」——省,但丢的是细节和位置 |
| LLaVA 2023 | 投影成 token | 极简主义:一个线性投影层就够了。 开源、便宜、效果出人意料地好,直接确立了「投影成 token」这条主流路线 |
| Qwen-VL 2023 起 | 动态分辨率 | 把固定分辨率改成「按原图比例切 tile」(把大图切成几块小图分别编码)—— 任意长宽比、任意分辨率都能处理。当前开源多模态的实际标准做法 |
| GPT-4V / Gemini 2023 起 | 闭源 | 工程细节未公开。Gemini 从设计上就是原生多模态:不是给语言模型挂眼睛, 而是一开始就在混合模态数据上训练 |
| 原生 Any-to-Any 2024 起 | 统一 token | 文本、图像、音频、视频全部用同一套 token、同一个 Transformer 处理, 输入输出都可以是任意模态。这是「拼接式」的终点 |
拼接式是主流:先训一个很强的语言模型,再挂一个视觉
互动 · 一张图,各条路线花多少
| 代价 | 说明 | 什么时候真的会痛 → 换什么 |
|---|---|---|
| 视觉 token 挤压上下文 | 一张 1024 的图就占 1,369 个 token(切 tile 的 2,560)。128K 上下文听起来很大, 但按这个量算,几十张图就满了。而且这些 token 里大部分是空白背景和无关细节 | 要一次传很多张图,或传高分辨率文档 → 降分辨率、限制每轮图片数,或改用能压缩视觉 token 的方案 |
| 视觉 |
它的「眼睛」是在自然图像上训的。面对医学影像、卫星图、电路图这些专业领域, 它提取的特征可能从一开始就不对——后面的语言模型再强也救不回来 | 要做专业领域的图 → 别只训投影层,把编码器也解冻微调(或换一个在该领域上训过的编码器) |
| 跨模态幻觉 | 模型会描述图里根本不存在的东西。原因和纯文本幻觉同源: 它的目标不是「说真话」而是「生成像描述的东西」。 更麻烦的是——你没法像文本那样用检索来验证一张图的描述 | 场景对准确性要求高(发票、仪表读数、医嘱)→ 不信自然语言描述,改用检测 / 定位这类可核对的输出 |
| 空间推理很弱 | 「左边第几个」「上面那个和下面那个之间的」—— 把二维空间压成一维 token 序列之后,位置关系被严重破坏。 这是当前多模态最明显的短板之一 | 问题真在「位置」上 → 换成检测 / 分割模型,或先把坐标标注进提示里 |
| 评测困难 | 「描述这张图」没有标准答案。用人工评太贵、用 GPT 评会继承它的偏好、 用 benchmark 又会被针对性优化。这个领域至今没有一个公认的可靠指标 | 要用它做上线决策或比较两个模型 → 自建一小套人工评测集,别只看公开 benchmark |
| 数据质量参差 | 网络上爬来的图文对大量是「图不对题」—— 电商列表图配的是泛泛的标题、表情包配的是无关文字。 清洗图文数据的难度远高于清洗纯文本 | 要自己爬图文数据 → 先把图文一致性过滤做在前面,再谈训练 |
跨模态那三条代价(时序一致性、音频序列长度、指标不可比)—— 上一章《一套机制,四种模态》已经逐条算过(那一章); 这一章只留视觉自己的六本账。
互动 · 二维格子拍平成一条线之后
这一章看起来在讲「怎么把图塞进语言模型」。底下其实只有一件事: 给不同的模态找一种共同货币。
回到「数学 · 还能装下几张图」那节,把「图像边长」从 224 拖到 2048:K 会塌下去——边长翻倍,一张图的 token 数就翻四倍。
再把「上下文窗口 B」拖到 1M:整条线抬起来,但抬的速度赶不上分辨率吃掉的速度。视觉 token 贵,贵在平方。
暗线是全站拆解一个方法的六个固定追问(信息怎么流动、什么被牺牲、参数账本……)。这一章只挑有实料的三条说。
| 暗线 | 这一章的回答 |
|---|---|
| A 信息流动 | 形状只降维,不变形:[高, 宽, 3] 切成 P×P 的 patch 变成 [N, P²·3]
→ 编码器 → [N, d_视觉] → 投影层 → [N, d_语言],再拼到文本 token 前面。
(方括号是形状;N 是切出来的块数。) |
| B 什么被牺牲了 | 牺牲模态自身的结构(二维邻接、时间连续性)和压缩的有损性,换来一个不用改造的训练栈:KV cache、批处理、上下文管理直接复用。 |
| C 参数账本 | 以 1024² 为例:切成 5,329 个 patch(floor((H−P)/P)+1);2×2 合并后 1,369 个 token,切 9 个 tile 则 2,560 个。
投影层把 1024 维视觉特征投到 4096 维语言隐藏层,两层 MLP 约 21M,在 7B 里只占 0.30%。 真正贵的是 token:2,000 个视觉 token 在 7B(32 层 × 32 KV 头 × 128 维,FP16)多出 2(K、V)×32×32×128×2000×2 字节(FP16 每数 2 字节)≈ 1.05 GB 的 KV 缓存(《KV Cache》)。 |
把图折成一串 token 拼到文本后面,语言模型一行不改就能看图——三条接法里赢的是「投影成 token」,因为它最不动别人, 代价是视觉 token 贵且压缩有损。
所以呢:别只看模型描述得流不流畅——去看它在小字、密集文本、空间关系上的表现。它接住了上一章《一套机制,四种模态》的接口问题,《缩放定律》接手规模。
上面讲的都是「够用」的版本。想往下挖,这里有三个入口—— 它们不是必修内容,是给想再往前走一步的读者准备的。