给模型一张菜单,问它「第二行的价格是多少」,模型需要先保留小字,再找到第二行,最后把数字读出来。如果预处理已经把字缩成模糊的一团,后面的语言模型再大,也无法从图像中找回被丢掉的笔画。视觉模型的设计,首先是在决定保留哪些信息、让哪些区域交换信息,以及把多少信息交给下游。
Vision Transformer(ViT)把图像切成 patch,用 Transformer 在这些 patch 之间交换信息。今天许多多模态模型仍沿用这个骨架,但在分辨率、位置编码、预训练和输出压缩上有不同选择。本文先从输入推导基本 ViT,再沿着这些选择理解实际模型。Attention 的更多变体见这一篇,视觉自监督目标见 SSL。
模型部分按 2026-09-22 可核对的论文、官方权重配置与实现展开,覆盖常见视觉 backbone、多模态模型,以及能说明不同设计方向的公开 encoder。公开权重不等于公开完整训练过程;本文把已经确认的结构与根据结构作出的分析分开,具体尺寸以指定 checkpoint 为准。
怎样把一张图交给 Transformer
从像素到 patch token
Transformer 接受一串向量。最直接的办法是把每个像素当成一个 token,但一张
折中的办法是先把相邻像素组成小块。设 RGB 图像为
个 patch。每块展平后有
这里使用 row vector,
Patch embedding 不需要显式地切出一堆小图片:Conv2d(C, D, kernel_size=P, stride=P) 可以实现同一个线性操作,输出再从空间网格展平成序列。因而「ViT 不用卷积」通常指主体采用 Transformer,并不排斥卷积形式的输入投影。
更小的 patch 会产生更密的空间采样,但也会增加序列长度。较大的 patch 则让最早的投影一次处理更大的区域;这不等于对区域取平均,块内像素仍有各自的权重。不过,若
序列顺序并不会自动告诉模型二维位置
把 patch 按行展平之后,数组下标有了先后顺序,但没有位置输入的 self-attention 并不知道这个下标。若同时重排输入 token,输出也只会跟着重排。菜单上第二行和第三行即使有完全相同的价格,模型也需要知道哪个价格属于哪一行;只有内容向量还不够。
原始 ViT 给每个 token 加一个 learned absolute position embedding。若任务是分类,还在前面放一个可学习的 CLS token,让它通过 attention 汇总整张图:
CLS 是一个额外的读出位置,不对应某块像素。图像分类可以读它,也可以对 patch features 做 pooling;分割、定位或多模态理解则往往需要保留 patch 序列。ViT 不要求一定有 CLS,也不要求最后只输出一个向量。
当网格从
每个 patch 怎样借用其他区域的信息
菜单上的一个笔画可能属于数字 3,也可能属于 8;只看局部不够,还需要同一个字符附近的笔画和整行布局。Attention 让每个 token 根据当前内容选择需要读取的其他 token。
对 normalized features
Query 与每个 key 的内积衡量匹配程度,经 softmax 变成一组和为 1 的读取权重,再对 value 加权求和:
Softmax 沿每个 query 对应的 key 维度进行;
读到其他区域的信息后,还要在每个位置内组合特征。于是一个典型 pre-norm block 是
Attention 负责位置之间的信息交换,MLP 负责每个位置内部的通道变换,residual connection 保留原有表示。现代模型可能换成 RMSNorm、SwiGLU 等,但这个分工仍然有用。经过多层之后,一个 patch feature 已经包含上下文,不能再把它理解为原始小方块的独立描述。
现在可以把位置问题再往前推进一步。找菜单中某道菜的价格时,「同一行、右边」比「图像第几个格子」更容易迁移到另一张排版相似的菜单。我们希望整对 patch 同时平移后,二者的空间关系不变;还希望加入位置时不任意放大内容向量。旋转正好满足第二个要求:它改变方向,保持长度;若两个向量都额外旋转相同角度,内积也不变,因此第一项要求也有了实现途径。
具体地,把通道两两分组,让位置为
这就是 RoPE 把相对位移放进内容匹配的方式。2D RoPE 分别为行、列坐标分配通道组与旋转频率,使横向距离和纵向距离可区分。不同实现会选择不同的频率和坐标尺度;它解决的是空间关系的表示,超出训练尺度的泛化仍需验证。Absolute embedding 与 RoPE 也可以同时使用:前者给单个位置提供地址,后者直接影响两个位置之间的比较。
有了这些部件,如何让网络真的学会识别?原始分类 ViT 在最终 CLS 上接 classification head,用真实类别的 cross-entropy 训练,梯度经过各层一直回到 patch projection。局部笔画检测、跨区域读取和全局汇总是共同学出来的。与卷积逐层扩展局部感受野相比,full attention 从第一层就允许远处位置交换信息,但「应该优先利用邻近结构」也更多交给数据与训练来学习。菜单问答的目标更细,不能只靠一个整图类别;接下来既要保留更密的输入,又要设计能利用这些位置的输出。
分辨率为什么会变成设计的中心
假设 patch size 固定,把高宽都放大两倍,token 数会变成四倍。Full attention 的矩阵大小是
| 输入尺寸 | patch 网格 | patch tokens | 单个 head 的 attention 矩阵元素数 |
|---|---|---|---|
| 196 | 38,416 | ||
| 784 | 614,656 | ||
| 3,136 | 9,834,496 |
表中忽略 CLS 等额外 token。对固定宽度,attention 的两次核心矩阵乘法约为
要保留菜单的小字,又不能无限增加计算,有三种不同层次的调整。
先改变输入。 把整张图缩放到固定正方形最简单,却可能扭曲长宽比或丢掉小字。Dynamic resolution 根据原图比例和像素预算选择网格;「native resolution」在实际实现中通常仍包括预算限制、resize 和整除对齐,不等于始终逐像素使用原图。
再改变通信范围。 每个 token 只在含
还可以切成多个 crop。 对一张很长的菜单,把各段分别放大后送入已有的固定尺寸 encoder,就能在复用同一套权重的同时保住笔画。若每块有
窗口与 crop 不是同一个操作:窗口可以在同一个 encoder 的后续全局层互相通信;独立 crop 在进入融合模块之前则是不同的视觉序列。两者也都不能替代位置编码。
从 ViT 输出到 LLM 输入,还差什么
一个 encoder 输出
保留空间网格,合并相邻特征
若希望压缩之后仍能对应图像区域,最直接的办法是每次合并相邻
输入维度从
也可以直接对邻域取平均,再投影。这样同样减少位置数,但平均会先抹掉组内差异;concat 则允许后续层区分「左上角是什么」与「右下角是什么」。这是一种表达能力与计算量的取舍,并不意味着 concat 在所有任务上都更好。
让固定数量的 query 主动读取图像
另一种目标是:无论输入有多少 patch,都只交给 LLM
其中
无论使用 merger、pooling 还是 resampler,在 ViT 之后压缩,只节省压缩之后的计算。ViT 已经处理过的 patch 不会因此变少。做延迟分析时,需要分别记录 encoder 的 token 数与送入 LLM 的 token 数。
下游为什么也在意这个长度?设文字有
还有一个接口差别:常见 merger 和固定 learned-query resampler 在看到问题之前,就已经把图像压好了。这使同一份视觉特征可以服务不同问题,但也意味着它们必须提前保留可能被问到的细节。它们不会因为用户随后问「第二行」就自动重新读取已被丢弃的原始像素;若系统需要按问题重新裁图或调高分辨率,那是另外一条输入与推理流程。
怎样从这些向量学会回答「18」
到这里,我们只是让图像变成 LLM 可以接收的一串向量,尚未教会 LLM 使用它们。对图中的菜单,可以构造一个训练样本:输入菜单和「第二行的价格是多少」,目标答案是「18」。令视觉序列为
这里
如果只更新 connector,梯度仍需穿过 LLM 才能告诉 connector 哪些视觉特征有用,但 ViT 和 LLM 的权重保持冻结;联合训练则可以继续调整它们。前一种方式先建立接口,后一种方式让视觉表示适应实际问答需求。这个 loss 只告诉网络最终答案是否正确,未显式标出「应该看哪一个 patch」;这也解释了为什么预训练特征、OCR 与定位数据会影响模型能否学到可靠的读取方式。
CLIP:让图像与文字落在可比较的空间
前面的问答 loss 需要一个已经能表示图像的 encoder。怎样预训练它,决定了 connector 最初能读到什么。假设菜单的配文只有「今日午餐」:认出这是一张菜单,就可能完成图文匹配,却没有理由精确区分价格 18 与 19。这个例子说明,architecture 决定信息怎样流动,训练目标还会决定哪些信息值得保留。
CLIP (Radford et al., 2021) 从成对的图像与文字出发。视觉 encoder 把图像变成一个全局向量,text encoder 把配文变成另一个向量;二者经过投影和长度归一化后,内积就可以表示语义相似度。CLIP 的视觉分支既有 ResNet 版本,也有 ViT 版本,这里关注后者。
设一个 batch 有
推理时,可以把候选类别写成文字描述,比较它们与图像的相似度;也可以给一段文字,在图像库中找相似向量。这解释了 CLIP 为什么能把分类与检索放进同一个接口。它本身并不逐字生成答案,也不输出菜单价格所在的框。
当 CLIP ViT 被接到 LLM 上时,通常需要取 pooling 之前的 patch features。这些位置虽然都受过全局训练信号影响,却没有逐一被要求保留字符、边界或精确坐标。于是,下一个问题不是简单增加一层投影,而是让预训练也关心这些局部信息。
SigLIP 2:同时学习图文语义、区域与局部特征
SigLIP 2 保留图像与文字两条 encoder 的基本结构,扩展了训练目标、语言覆盖和可用输入形状 (Tschannen et al., 2025)。它既可以提供整图 embedding,也可以把未汇总的视觉特征交给多模态模型。理解它时,需要区分图文配对的 loss、对局部表示的监督,以及 NaFlex 的输入路径。
先看图文配对。CLIP 的 softmax 让一张图的所有候选文字在同一个分母中竞争。SigLIP 则把每一对图文当成一个「是否配对」的判断:正例得分应当高,负例得分应当低。用
对正例,增大
只改变配对 loss,仍然不能强迫模型读清菜单上的小字。SigLIP 2 因而引入 LocCa 式的训练 decoder,让它读取未汇总的视觉序列,完成图像描述、根据文字定位区域、根据区域生成描述等任务。比如训练目标从「这是一张菜单」变成「给出第二行菜名所在的区域」,encoder 就必须提供能区分行与列的特征;从指定区域生成文字,又要求局部内容能够被语言读出。这个 decoder 服务于预训练,不能把它与下游聊天模型的 LLM 混为一谈。
固定分辨率版本还用视觉 self-distillation 与 masked prediction 改善 dense features。前者让看局部 crop 的 student 学习看较大 view 的 EMA teacher 所提供的语义目标;后者把 student 的部分 patch 输入遮住,要求对应位置预测 teacher 在完整 view 上产生的目标。Teacher 的输出不参与反向传播,参数随 student 做移动平均。这样,模型既要从局部辨认整体语义,又要借助上下文恢复某个位置应该表示什么;监督不再只经过最终的整图 embedding。
这里的「恢复」主要是特征或目标分布层面的预测,不是把原始 RGB 像素逐个画回来。也正因为监督形式不同,图文 loss、区域任务和 masked prediction 可以作用于同一个 ViT,却分别对跨模态对应、空间定位和局部表示施加压力。
NaFlex 解决的是另一个问题:怎样让一个 checkpoint 接受不同形状的图。 对一张很长的菜单,强行缩成正方形会改变字形;先等比例缩放再大面积补白,又可能浪费 token 预算。NaFlex 在给定 patch size 和最大序列长度后,尽量保持原长宽比,把高宽调整为 patch size 的倍数,并保证 patch 数不超过预算。随后生成 patch 坐标和 padding mask,把二维 learned position embedding 插值到实际网格,attention 与 pooling 时忽略补齐的位置。
例如
NaFlex 通过多种序列长度训练来适应这些变化,而非只在推理时临时插值。还需注意论文中的配方边界:NaFlex 沿用了图文与区域训练,但没有加入上述 self-distillation 和 masked prediction。固定分辨率与 NaFlex 是同一家族中的不同训练方案;下游写「SigLIP 2 初始化」,也未必表示直接使用 NaFlex 的完整 processor。
DINOv3:保护每个空间位置之间的关系
如果没有图像配文,能否仍然得到有用的视觉特征?DINOv3 的主要视觉预训练从图像本身构造监督:同一张图的不同 view 应该表达相容的语义,被遮住的位置则应当能从周围上下文中推断 (Siméoni & others, 2025)。它学习的是可迁移的视觉表示,随后才根据分类、分割、深度估计或多模态任务接上不同的 head。
这条路线同时维护 student 和 EMA teacher。Teacher 为较完整的 view 产生目标,student 处理不同尺度的 crop 或带 mask 的输入。DINO 的全局目标对齐整图表示,iBOT 的 patch 目标监督被遮住位置的表示;二者都通过 learned projection head 产生训练目标分布。Teacher 停止梯度,再用 student 参数的移动平均更新,避免两个分支通过同一次反向传播直接追逐彼此。关于避免所有输入坍缩到同一个输出,以及目标分布怎样构造,见 SSL 的 DINO 系列部分。
对下游而言,最有用的结果之一是空间特征网格。输入为
全图汇总与局部忠实之间确实存在张力。网络可能借一些信息较少的背景 patch 存放全局计算结果,使它们出现异常高的特征范数。Registers 为这种工作提供额外的、不对应像素的 token (Darcet et al., 2023)。它们和 CLS、patch 一起参与 attention,但读出空间网格时应当排除;否则,额外的工作位置会被错误地当作图像的一部分。
DINOv3 又发现,长时间训练后,即使全局任务继续变好,dense features 的局部结构也可能退化。继续提高整图识别能力,并不自动保证相邻物体边界保持清楚。它的 Gram anchoring 因而选择一个空间特征较好的 teacher,约束 student 保持「哪些位置彼此相似」。
为什么约束相似关系,而不直接复制每个特征?设两块 patch 都属于同一片叶子,另一块属于背景。我们希望前两者仍然接近、与第三者保持区别,但不要求「叶子特征」永远指向特征空间中的某个固定方向。把每行归一化后的 patch features 排成
恰好收集了所有位置之间的相似度。因此,用 student 的
Frobenius norm 把所有位置对的差异平方后相加;训练中再用权重控制这一项的重要性。若 student 的全部特征共同乘上一个正交矩阵
Gram teacher 与普通 EMA teacher 也不是同一个更新过程:它从较早、局部特征较好的 checkpoint 初始化,在 refinement 阶段较慢地更新。高分辨率 teacher 还可以先生成更密的特征,再缩回 student 的网格提供目标。公开的小模型可以由大 teacher 蒸馏得到,不能把大模型的全部预训练阶段原样归到每个小 checkpoint 上。
在结构上,DINOv3 的 ViT 使用 RoPE 来编码空间位置,并结合相应的分辨率适应训练。位置编码使不同网格更容易进入同一模型,但并不意味着输入越大、效果就必然越好。更关键的是,DINOv3 的特征相似度本身没有规定「这个图案应读作 18」:接入 LLM 后,仍需要图文对齐或问答训练建立语言对应。
Qwen2.5-VL:在高分辨率网格上交替做局部与全局读取
到了完整的多模态模型,视觉 encoder 还要与 processor、connector 和语言模型共同工作。Qwen2.5-VL 的一个主要设计问题是:菜单、长文档和普通照片的形状差别很大,怎样保留细节,又不让每个视觉 block 都承担完整的二次 attention 成本?它采用动态网格,并在大多数 ViT 层限制通信范围 (Bai & others, 2025)。
先沿着一张图走一遍。Processor 根据像素预算调整尺寸,并把高宽对齐到 28 的倍数。这个 28 来自两步操作:
动态网格让长图继续保持长图的布局,但 1536 个位置如果在每一层都两两比较,仍然很贵。Qwen2.5-VL 的 32 层视觉 Transformer 中,第 8、16、24、32 层做 full attention,也就是从 0 开始计数的索引 7、15、23、31;其余层使用至多
在这个
而全局层为
这不是总 FLOPs 或实际时间的比例,因为 projection、MLP 等仍然处理全部 1536 个位置。它准确说明了窗口省掉哪一种操作:大多数层不再为每个 patch 比较全图所有 key。
局部层可以先处理笔画和附近布局,全局层再让不同窗口交换菜名、价格、表头等信息;后面的局部层也会继承此前的全局上下文。窗口并没有把整张图永久切成互不相见的 crop。视觉侧的 2D RoPE 为这种读取提供空间关系,RMSNorm 与 SwiGLU 则调整 block 内的归一化和通道变换;它们本身不改变 token 数。
对于视频,还需要处理时间。视觉入口会把相邻帧组成 temporal patch;LLM 侧的 MRoPE 则为视觉 token 分配时间、高度、宽度坐标。Qwen2.5-VL 把时间坐标与实际时间对齐:同样间隔一个采样帧,在 1 FPS 与 10 FPS 下分别对应一秒和十分之一秒,不应当被当作相同的真实时间跨度。这个设计要和训练中的动态 FPS 配合。
视觉侧的 2D RoPE、入口处的短时间分组,以及 LLM 侧的时间位置编码分别解决不同问题。仅仅看到 MRoPE 中有时间维度,不能推断 ViT 已经在所有视频帧之间执行了全局 attention;读实现时仍要检查 attention 的实际分组边界。
Qwen3-VL:把多个视觉深度接入语言计算
Qwen3-VL 在视觉预训练与视觉特征的使用方式上继续调整。其 encoder 从 SigLIP 2 初始化,再进行动态分辨率训练,结合插值后的 absolute position embedding 与 2D RoPE;常用配置采用 So400M 分支,2B、4B 等较小语言模型对应的是 Large 分支,不能把同一组视觉尺寸套在整个家族上 (Qwen Team, 2025)。
以 Qwen3-VL-8B-Instruct 为例,视觉宽度为 1152、深度为 27、patch size 为 16,最终仍通过
真正需要进一步解释的是 DeepStack。只取视觉最后一层时,所有对答案有用的证据都必须经过最后一层及其 merger。网络越往后,特征可能越倾向于当前训练目标需要的抽象表示;前面仍然有用的纹理、形状和局部结构,未必都以易于下游读取的形式保留下来。
一种直接办法是把三层中间特征也拼进输入序列。但若每层都贡献 294 个位置,原来的 294 会变成 1176,LLM 在每个 block 都要处理更长的序列。Qwen3-VL 选择沿网络深度补充信息:不同视觉层先经过各自的 merger,得到与原视觉位置数量、宽度相同的向量,再加到 LLM 早期层的这些位置上。
设视觉层
第二个式子表示此次加法不直接修改文字位置;之后的语言层仍可以通过 attention 读取更新后的视觉状态。因为相加的两项形状相同,序列不会变长。额外成本来自中间特征的保留、多个 merger 和注入路径,而非多出三份上下文位置。
这个 8B checkpoint 选择的视觉 block 索引为 8、16、24,即从 1 计数的第 9、17、25 个 block;这些分支进入 LLM 的前三层。最终视觉输出仍负责初始化输入中的视觉位置。这里不应给某一路强行贴上「专门负责 OCR」的标签:多层路径提供了可学习的选择,具体分工由训练形成。Qwen3-VL 采用的是多深度特征,亦有别于原始 DeepStack 中使用多尺度输入的方式。
视频位置也有两项变化。首先,interleaved MRoPE 把时间、高度和宽度的通道分散到不同旋转频率中。若把三个坐标轴各自连续分成一大段,而频率沿通道递减,就可能让某个轴主要占据高频、另一个轴主要占据低频;交错分配让三个轴都能获得不同尺度的位置变化。
其次,帧组前加入可读的文本时间戳,例如「3.0 seconds」。Qwen2.5-VL 主要通过时间 position ID 表达绝对时间;Qwen3-VL 把实际时间直接写入序列,让时间定位也能使用语言表示。时间戳会增加少量文本位置,但 DeepStack 本身不增加视觉位置,两件事不能混算。
这些结构还需要相应训练才能奏效。Qwen3-VL 先建立视觉与语言接口,再解冻模块联合训练,并逐步扩展到长上下文;OCR、grounding、图表与视频等数据教会模型利用这些证据。接入更多视觉层只是打开路径,训练才决定模型是否真的能从那条路径读到正确价格。
Qwen3.5:视觉入口继续保留,联合建模方式发生变化
Qwen3.5 的官方说明强调 early fusion 的多模态训练,即在基础模型训练中共同学习视觉与语言,而不只把视觉看作最后追加的问答能力 (Qwen Team, n.d.a)。这里的 early fusion 描述训练和模态融合方式,不等于取消视觉 encoder,也不等于把原始 RGB 当作文字 token。
沿 Qwen3.5-9B 的配置追踪,仍然可以看到独立视觉分支:27 层、宽度 1152、
但相同尺寸没有保留所有相同的数据路径:这个 checkpoint 的 DeepStack 视觉索引列表为空,没有 Qwen3-VL-8B 的那三路中间层注入。由此能确认的是已发布模型采用的连接结构;不能仅凭这一字段,推断去掉 DeepStack 的独立性能收益、权重初始化来源或完整训练消融。
另一个明显变化在语言侧。9B 配置把 Gated DeltaNet 与 full attention 交替使用,使长序列不再在每一层都走相同的 full-attention 路径。对多模态输入而言,这会改变 294 个视觉位置进入共享模型之后的处理成本;它并不会反过来把前面的 ViT 自动变成 linear attention。视觉 token 数与语言网络怎样处理这些 token,是两个需要分别核对的维度。
Qwen3.8:沿既有视觉接口扩展完整模型能力
截至本文核对时,Qwen 已公开 Qwen3.8-27B。它的官方 model card 将其描述为建立在 Qwen3.5 架构基础上的原生视觉语言模型,重点覆盖图像、视频以及更长的多步任务 (Qwen Team, n.d.c)。对理解 ViT 来说,这一代有价值的观察是:完整模型能力继续更新,并不要求每次都重新设计 patch 接口。
Qwen3.8-27B 的公开配置仍使用 27 层、宽度 1152、
这也给阅读新版本提供了一个具体方法:先确认输入网格与连接方式有没有变化,再把模型卡中有关推理、工具或长任务的改进放到整个系统中理解。两份配置相近,不能证明视觉权重相同;同一视觉接口接上不同语言模型、训练数据与优化过程,也可能产生不同的文档理解行为。官方配置足以确认这里的数据流,尚不足以把所有能力变化归因于某一个视觉部件。
InternVL3.5:先把大图分成 tiles,再按内容分配输出预算
InternVL3.5 延续 InternViT–MLP–LLM 结构,通过动态数量的 tiles 处理高分辨率输入 (OpenGVLab, n.d.)。它优先复用固定大小的视觉视图:根据原图的长宽比和最大 tile 数选一个网格,把大图调整到这个网格后切块,再把各块分别送入 encoder。必要时额外加入整张图的 thumbnail,以保留整体布局。
这里有两种容易混淆的「块」。Tile 是一次送入 encoder 的
以原图恰好适合
切块的代价也由此清楚了:把一张图切成六块,确实让每块能保留更多细节,但同时增加 encoder 调用量和 LLM 输入量。只看「每 tile 256 tokens」,会漏掉 tile 数这个乘数。
InternVL3.5-Flash 进一步问:每个 tile 都值得用 256 个输出位置吗?它增加 Visual Resolution Router(ViR),在常规的 256 tokens 与更强压缩的 64 tokens 之间选择 (Wang & others, 2025)。后一条路径相当于把
例如四块局部视图中,两块保留 256、两块保留 64,总量就是
而统一保留 256 时为 1024。Thumbnail 和其他图像仍需另计。这个路由发生在 ViT 特征已经生成之后,所以主要减轻 LLM 负担;它没有省掉这四块各自的 1024-patch 编码。
Router 也不是凭「看起来有多少边缘」就能可靠判断压缩是否安全。一个很小的价格数字可能纹理不复杂,却决定整个问题的答案。InternVL3.5-Flash 因而通过 Visual Consistency Learning(ViCO)让压缩选择与任务输出联系起来。
第一步,固定一个使用 256-token 路径的 reference model;训练另一个模型,在随机使用 256 或 64 tokens 时,仍尽量保持 reference 的答案分布。对每个答案位置,reference 告诉 student 哪些下一词概率值得保留,KL divergence 衡量两者的差异。这一步让网络学会利用较少特征,而不只是机械删掉位置。
第二步,冻结主体网络,观察更强压缩会令答案分布偏离多少,再用这种相对损失变化构造 router 的训练标签。压缩影响很小的 tile 可以走 64-token 路径,影响大的则保留 256。由此,ViR 学习的是「这块内容能否承受更强压缩」,而不是一个抽象的图像复杂度分数。
InternVL3.5 还有用于改善回答与推理的后训练步骤。它们能改变模型怎样使用视觉证据,却不应当与 tile 网格、pixel shuffle 或 router 的结构作用混为一谈:输入细节、传给 LLM 的容量和答案训练共同决定最终表现。
MiniCPM-V 4.5:用有限的 query 联合读取空间与时间
如果输入换成摄像头拍摄菜单的视频,相邻帧可能几乎一样。逐帧保留同样多的 LLM tokens,会反复为同一片背景付费;先把像素平均,又可能把镜头运动造成的文字位移混成重影。MiniCPM-V 4.5 选择先编码各帧,再用 3D-Resampler 联合读取一组帧的视觉特征 (OpenBMB, n.d.)。
它基于 SigLIP 2 视觉 encoder 与 Qwen3 语言模型,公开配置中的 patch size 为 14,resampler 的 query 数为 64 (OpenBMB, n.d.b)。对一张
这与把每
视频中再加入时间坐标,就能区分「某个数字在第一帧出现」与「它在后面一帧发生变化」。3D-Resampler 可以把一组连续帧的空间特征一起作为读取来源,输出仍是 64 个向量。相似内容有机会共享表示,运动或变化则通过联合特征与时间信息进入输出;这不是把整个 clip 先变成一张平均图。
官方例子使用六帧
若对照的是「每帧先压到 256,再送入 LLM」,六帧原本贡献 1536 个位置,那么相对这条路径的下游长度比值是
更长的视频需要更多帧组,高分辨率图像的 slices 也需要分别计入。六帧共用 64 个输出,省的是这组帧进入 LLM 的长度,并没有免除六帧的视觉编码。同时,一个固定容量的出口必须在重复背景与短暂事件之间取舍;若任务要求逐帧读取快速变化的小字,就需要检查抽帧、分组、空间分辨率和压缩后的实际保真程度。
MiniCPM-V 4.6:把一部分压缩提前到 ViT 内部
MiniCPM-V 4.6 在 2026 年公开,采用 SigLIP 2-400M 与 Qwen3.5-0.8B 语言模型,重点面向较小部署规模 (OpenBMB, n.d.c)。它引入 4×、16× 两种视觉压缩模式;这里的重要变化是压缩的位置,不能把它理解成仅仅换一个 query 数的 4.5。
方法来自 LLaVA-UHD v4 (Fang et al., 2026):如果所有压缩都放在 ViT 后面,前面每一层始终要处理长序列。能否先让较早几层提取局部特征,再缩短网格,让后面大部分视觉层也少做一些计算?
最简单的办法是中途直接平均相邻位置,但这样可能在特征还没准备好时就混掉细节。它采用的模块先让相邻
这一步的意义不只是换一种 pooling。局部 attention 可以先整理同一区域内的互补证据,拼接保留四个来源的通道位置,MLP 再学习如何压到一个向量。论文还从相邻预训练层复用参数来初始化新模块,降低在网络中间插入随机变换造成的扰动;压缩后的表示仍需经过训练适应。
MiniCPM-V 4.6 的配置有 27 个视觉 blocks,插入索引为 6 (OpenBMB, n.d.d);当前官方 Transformers 实现从 0 计数,在完成对应 block 后执行合并,即完成前 7 个 blocks 后再压缩 (OpenBMB & Hugging Face, n.d.)。以一个处理后为
前一次合并减少后续视觉层的输入长度,后一次合并再减少交给 LLM 的长度,二者合起来才是
切到 4× 模式时,当前实现跳过内部 merger,保留全部 27 层中的较密网格,只在输出端合并到 256 个 LLM tokens。这个开关因此同时改变后半段 ViT 的长度和 LLM 输入长度,而非只在最后把 64 改成 256。
面对菜单 OCR,可以先考虑较密的路径是否更适合保留笔画;面对多帧概括,则可以接受更强的压缩。这样的选择需要在实际任务上检验。4.5 的跨帧 query resampling 与 4.6 的中途空间合并,分别解决时间冗余和视觉计算负担,不能把两个版本的压缩比例相乘,当成同一个 checkpoint 自动具备的能力。
OneVision-Encoder:在进入 ViT 前选择变化
前面的压缩分别发生在 ViT 之后或内部,但入口仍先接收完整视图。若 64 帧大多重复,能否更早利用帧间冗余,让第一层就少看一些没有变化的背景?OneVision-Encoder(简称 OV-Encoder,与 LLaVA-OneVision 不是同一个模型)把视频编码器已有的信息变成了一个选择器 (Tang et al., 2026)。这里保留它作为另一类公开 encoder 的具体例子。
视频编码利用一个事实:下一帧通常可以从已经出现的画面预测出来。Motion vector 告诉 decoder 去参考帧的哪里取内容,prediction residual 则补上预测没有解释的部分。比如镜头固定而手指划过菜单,静止的桌面可以反复引用,手指及被遮挡的文字附近则需要描述变化。关于这些信号如何产生,见媒体压缩中的视频部分。
OV-Encoder 采用 HEVC 预处理,把 clip 组织成 Group of Pictures(GOP)。其 I/P 路径对 I-frame 保留完整空间网格;对 P-frame,则把 motion vector 的幅值与亮度 residual 的能量聚合到 ViT patch 网格,再在整段视频的预算内优先选择变化显著的位置。Motion 与 residual 分别提供「内容移动了多少」和「预测还漏了多少」的线索,但二者都不是物体或动作的语义标签。
这里 motion vector 和 residual 只负责决定选哪里;真正输入 ViT 的仍是解码后的 RGB patch,而不是压缩码流中的运动向量或残差。这样既利用了 codec 已经找到的冗余结构,又让视觉 backbone 保持对 RGB 内容的读取方式。
以论文的默认视频设置为例,64 帧、GOP 长度 32 会产生两个 I-frame。若每帧原本有 256 个 patch,dense 编码需要
个 patch;总预算
这是 ViT 输入 patch 数的减少,不代表端到端延迟恰好提升八倍;视频解码、筛选、attention 之外的层和后续模型都仍有成本。
筛选也带来新的位置问题。某个 P-frame 可能只保留原网格的第 3、8、14 块,压紧后的序列下标却是连续的;若按下标做位置编码,模型会误以为这些 patch 在时空中相邻。OV-Encoder 因而让每个 token 携带原始
同一个 ViT 因此可以接受三种序列:图像保留完整空间网格;普通视频可按时间 chunk 采一帧并保留整帧 patch;codec 路径则保留 dense 时间采样、稀疏选择每个 P-frame 的空间 patch。后者并非总是占优:它依赖可取得 motion vector 与 residual 的 HEVC 预处理,也假设「编码残差大」通常能代理「语义上值得看」。I-frame 为静态区域提供底图,但细微且低残差的事件仍可能被固定预算漏掉。
Sparse patches 还需要明确的学习目标。OV-Encoder 用冻结视觉教师生成表示并离线聚类,建立图像的 object-level centers 与视频的 motion-level centers。可以把这些中心理解为视觉数据中反复出现的模式:一个样本可能同时含有多个物体或动作,因此它不必只属于一个互斥类别,而是可以对应多个正中心。
训练时,pooled visual embedding 分别判断与这些中心是否匹配,用 multi-label sigmoid loss 学习。它与前面 SigLIP 的联系在于独立的二元判断形式;区别在于目标来自视觉聚类中心,而非图文配对。之后再通过更高分辨率、视频与 OCR 相关监督拓展共享 backbone 的能力。这个过程让稀疏输入从训练阶段就与目标相适应,而不是把一个只见过完整帧的模型在推理时突然删掉大量 patch。
公开的 Large checkpoint 是约 0.3B 参数、
Gemma 3:先在高分辨率上编码,再固定每个视图的输出长度
Gemma 3 的 4B、12B、27B 多模态版本使用经过视觉任务适应的 SigLIP encoder;1B 版本不应当套用这条视觉路径 (Gemma Team, 2025)。对一张图,先得到
如果把这 4096 个位置全部交给语言模型,单张图就会消耗很长的上下文。Gemma 3 在视觉编码后做
为何先看 4096 个位置,再只留下 256 个?因为 pooling 发生在上下文编码之后。每个被平均的向量已经读过周围甚至远处的信息,encoder 有机会把小字的形状转换成更易保存的特征。它与一开始就把图缩小到只剩 256 个 patch 不等价:后者可能在任何学习模块看到笔画之前,就把笔画抹掉。
但后置 pooling 也没有无损保证。它把多个位置压到同一个向量,LLM 无法再把这 16 个来源分别当作独立位置读取。与拼接后 MLP 相比,average pooling 使用固定的聚合规则;模型需要让上游特征适应这个出口。高分辨率编码与较短语言输入,是分别发生在两段计算中的预算选择。
固定正方形视图对长菜单仍然不够友好:缩放会挤压布局,细字也可能太小。Gemma 3 提供 pan-and-scan,在需要时把原图拆成额外局部 crops,分别放大到 encoder 的输入尺寸,并控制最大 crop 数。它作为推理侧的可选处理,能通过增加视图保留更多细节。
例如一张原图保留一个整体视图,再增加两个局部 crop,就有三个独立的 256-token 输出,共 768 个视觉位置。这个算例不包含边界标记和文字,也不意味着 processor 对所有长图都会选两个 crop。它说明「每视图固定 256」与「每张原图固定 256」是完全不同的约束。
Gemma 4:由 token budget 决定可用的空间网格
Gemma 4 把视觉预算显式交给输入处理流程:官方提供 70、140、280、560、1120 等选项,并支持可变长宽比 (Google DeepMind, n.d.)。只想判断照片是否包含菜单时,可以尝试较小预算;要逐行读出密集文字,就更需要保留较多空间位置。预算是输入表示的上限,不是生成答案的最大 token 数。
先看仍然使用独立 encoder 的 Gemma 4-31B。其视觉配置为 27 层、宽度 1152、patch size 16、pooling kernel size 3,默认输出预算为 280 (Google DeepMind, n.d.b)。模型先在较密的 patch 网格上编码,再按
这使 processor 可以从下游预算反推出上游预算。若希望最多保留
以正方形输入为例,2520 个 patch 的面积预算对应约
于是预算设为 280,这张正方形图仍可能只有 256 个有效视觉位置。剩余容量可以用于张量补齐,但 padding 不应成为实际图像内容,也不应被算作向 LLM 提供的有效证据。不同长宽比会得到不同网格,不能用「280 tokens」反推所有输入都被缩成同一个正方形。
Gemma 4 的实现把二维坐标同时用于位置表示与 pooling:合并的是原网格中的邻近位置,而不是把展平数组中随便连续九个元素平均。Padding 位置也需要排除 (Google & Hugging Face, n.d.b)。这与前文稀疏 token 的位置问题相呼应:序列是存放向量的方式,二维坐标才告诉模型哪些向量在图像中相邻。
调大这个预算会让 processor 保留更大的网格,既增加 encoder 的工作,也增加合并后的 LLM 输入。它和 InternVL3.5-Flash 在已经算好的同一份 ViT 特征上选择压缩率,控制的位置不同。实际排查延迟时,应同时观察 resize 后的 patch 数与有效 soft-token 数,不能把一个输出参数当成整条链的唯一成本。
Gemma 4 12B Unified:把视觉建模放进共享 Transformer
同属 Gemma 4 的 12B Unified 采用另一种架构。官方说明明确移除了独立视觉与音频 encoder,把原始图像 patches 和音频输入经过轻量线性投影,直接映射到共享模型的 embedding 空间 (Google DeepMind, n.d.a)。因此,上一节 31B 的 27 层视觉分支与
先只看图像。一块 RGB patch 仍然有很多数,它不可能未经任何变换就变成语言模型的 hidden state。轻量投影完成的是前文最早的那一步:把 patch 内的像素组合成一个输入向量。区别在于,这个向量不再先经过一个独立的深层 ViT,才由 connector 交接给 LLM;后续视觉信息的组合与多模态关系的建模由共享 Transformer 承担。
这把原来的模块边界移走了。在独立 encoder 的路线中,语言模型最先接触到的是已经过多层视觉处理的特征;在 encoder-free 路线中,共享模型更早接触低层视觉表示,训练必须让它逐步学会利用这些输入。视觉感知并没有消失,而是被安排在另一组共享参数中完成。
由这个数据流可以推得,它也改变了预算与适应方式:减少了一段独立 encoder 的执行和交接,但更多视觉处理落入共享网络。最终是否更省计算,仍取决于 patch 数、共享网络宽度、attention 范围和训练后允许的压缩方式,不能只根据「没有 ViT」得出任意分辨率都便宜的结论。
这也说明「现代多模态模型是否还用 ViT」需要落到具体版本回答。很多模型仍采用独立的 patch-based vision Transformer;另一些模型保留 patch 表示,却把其后的视觉计算融入共享网络。沿输入向量实际经过的层去看,比只根据家族名称分类更准确。
把完整请求的 token 账算清楚
前面的算例大多以一个处理后视图或一个视频帧组为单位,完整请求还需要把所有单元相加。原始图像数、encoder 输入单元数与 LLM 视觉位置数,通常不是同一个数。
假设一种 resampler 路径给每个视图 64 个输出,一张图被处理为一张 thumbnail 加四个局部 slices,那么这张原图贡献的是
把文字位置记为
它既不是「一张图加一段视频,所以只有两个 token」,也不是「图像和视频都支持 64-query,所以总共只有 128 个」。决定数量的是实际执行了多少次输出操作,以及每次输出多少位置。
Temporal patch size 也不能随便拿来除静态图像的 token 数。比如前面 Qwen 的配置涉及两帧分组,但静态图像走 processor 的图像路径,可以通过重复帧等方式满足入口形状;不能因此把已经算出的静态空间位置再除以 2。视频则要同时核对抽帧数、temporal grouping 和空间合并。
因此,应当同时记录
如果 encoder 内部还会下采样,
这条链也能帮助定位失败。小字在 resize 时消失,应该先检查输入预算;ViT 很慢,应该检查各阶段 patch 数和 attention 范围;LLM prefill 或上下文压力大,应该检查合并后的序列;局部特征已经存在却没有被答案使用,再检查 connector、注入方式与多模态训练。增加语言模型参数,只能改变这条链中的一部分。
怎样读一个新模型的视觉实现
先看 processor 实际输出的尺寸、crop 数、padding mask 和网格坐标,再沿 patch embedding 找到 encoder 的真实输入长度。对视频,还要确认抽帧或 patch 筛选发生在 ViT 之前,还是只在 ViT 之后压缩输出。随后检查位置编码、window/full attention 的分布,以及是否有 CLS 或 registers。最后追踪 connector 改变的是通道、位置数量还是注入层数,并核对送入 LLM 的实际张量。
模型名称和 image_size 默认值只能提供线索,不能代替这条数据流。例如,vision_config 中的默认尺寸可能用于初始化位置表,而 processor 仍支持动态尺寸;语言模型的 MoE、linear attention 或 sliding attention 也不能直接推断到视觉分支上。
读 ViT 时最有用的四个问题始终是:模型看到了什么分辨率,哪些位置能交换信息,训练让它保留什么,最终下游收到多少特征? 原始 ViT 给出一个简单骨架,而近期模型的不同设计,正是在这四个问题上作出不同回答。