RealCat

· 85 min read

交互式理解 DINO 系列:从自蒸馏到视觉基础模型

今天做视觉任务,很多人的第一步已经不是「找一个在 ImageNet 上训好的分类网络」,而是「把 DINOv2 或 DINOv3 的骨干拿来冻住,接一个很小的头」。深度估计、语义分割、特征匹配、三维重建、视觉定位,背后都站着这一家子模型。它们的共同点是:训练时没有用过一个人工标签,却给出了比有监督模型更通用的特征。

这篇文章沿着时间线把这个系列拆开讲:2021 年的 DINO 立下了「自蒸馏」这条主线,iBOT 给每个 patch 也加上了监督,2023 年的 DINOv2 证明数据和工程才是把它变成基础模型的关键,2025 年的 DINOv3 把参数推到 70 亿、图片推到 17 亿张,并解决了一个困扰很久的「密集特征退化」问题。每一代的核心机制都做成了页面里实时计算的小部件,可以自己动手试。

读这篇文章需要知道 ViT 是什么:图片切成 patch,线性投影成向量,加一个 [CLS] token,过若干层 Transformer 编码器。不熟悉的话可以先看交互式理解 Transformer,特别是第 11 节。

一个容易混淆的点:目标检测里也有一个 DINO(DETR with Improved deNoising anchOr boxes),以及由它发展出的 Grounding DINO。那是另一条线,名字撞了而已。本文的 DINO 是 self-DIstillation with NO labels,没有标签的自蒸馏。

第一部分:先看整体

0. 这个系列在解决什么问题

有监督学习的瓶颈从来不是模型,而是标签。ImageNet 的 128 万张标注图是十几年前的产物,而互联网上的图片以百亿计。自监督学习(self-supervised learning,SSL)的目标是只用图片本身训练出好用的特征。什么叫「好用」?DINO 系列采用的标准很苛刻:骨干网络冻结不动,在它输出的特征上只接一个线性层或者直接做 k 近邻(kNN),就要在分类、分割、深度估计等任务上拿到好成绩。做到这一点的模型,才配叫「视觉基础模型」。

下面是时间线。点每个节点看它做了什么,以及对应本文的哪一节。

202020212022202320242025 ViT DINO iBOT DINOv2 寄存器 DINOv3 2020.102021.042021.112023.042023.092025.08

点一个节点。

把三代主模型放在一张表里,能看出什么在变、什么不变:

DINO (2021)DINOv2 (2023)DINOv3 (2025)
训练数据ImageNet-1k,128 万张(有标签但没用)LVD-142M,1.42 亿张自动筛选LVD-1689M,16.89 亿张自动筛选
最大模型ViT-B/8,8500 万参数ViT-g/14,11 亿参数ViT-7B/16,67 亿参数
损失DINO(全局自蒸馏)DINO + iBOT + KoLeoDINO + iBOT + KoLeo + Gram anchoring
防坍塌中心化 + 锐化Sinkhorn-Knopp + 锐化同 v2
新东西自蒸馏框架;涌现的分割数据筛选流水线;蒸馏成模型家族;工程Gram anchoring;RoPE;常数学习率;文本对齐
ImageNet 线性探测80.1%86.5%(带寄存器 87.1%)88.4%
对下游最有用的注意力图、kNN 特征冻结骨干的密集特征高分辨率下干净的密集特征

不变的主线只有一条:自蒸馏。 一个学生网络和一个老师网络,结构相同;老师的权重是学生权重的滑动平均;学生看到的是图像的各种裁剪,老师只看到完整的大图;学生被要求在每个裁剪上都预测出老师的输出。三代之间变化的,是喂给这个循环的数据、模型的大小、以及用来堵住各种退化方式的正则项。

第二部分:DINO(2021):没有标签的蒸馏

1. 自监督在学什么,为什么会「坍塌」

自监督方法的共同出发点是一条朴素的直觉:同一张图的两种随机增广,应该得到相同的表示。 裁一块、翻个面、调个色,内容没变,特征就不该变。这叫「不变性」。

但只要求不变性有一个平凡解:网络对所有输入都输出同一个常数向量。不变性完美满足,特征毫无用处。这就是坍塌(collapse)。2020 年前后的方法主要在用不同的办法堵这个洞:

  • 对比学习(SimCLR、MoCo):把其他图的增广当「负样本」推远。管用,但需要很大的 batch 或一个负样本队列。
  • BYOL:不要负样本,用一个滑动平均的老师给学生当目标,并在学生那边多加一个「预测头」打破对称。
  • SwAV:不比向量,比「属于哪个聚类」,用 Sinkhorn-Knopp 算法强迫每个聚类分到的样本数均衡。它还提出了多裁剪(multi-crop)增广。

DINO 做了一次减法:拿 BYOL 的 EMA 老师,拿 SwAV 的多裁剪,去掉负样本、去掉预测头、去掉聚类,只在老师的输出上做两个极便宜的操作(中心化和锐化)来防坍塌。整个方法的伪代码不到 20 行。下面三节分别讲多裁剪、EMA 老师和防坍塌。

2. 多裁剪:从局部推断全局

DINO 对每张图采两种裁剪:2 个全局裁剪,覆盖原图 40% 到 100% 的面积,缩放到 224×224;若干个局部裁剪,只覆盖 5% 到 40%,缩放到 96×96。老师只看全局裁剪,学生看全部。损失要求学生在任何一个裁剪上的输出都去匹配老师在全局裁剪上的输出。这意味着模型要从猫耳朵的一角推断出「这是整只猫」:局部到全局的对应关系,正是让特征带上语义的来源。

主题色粗框:2 个全局裁剪(老师和学生都看);白色细框:局部裁剪(只有学生看)。

老师看到的(224×224)
学生额外看到的(96×96,这里缩小显示)

把局部裁剪数拉到 10,会看到很多裁剪里只有地板或者只有半只耳朵。模型必须让这些碎片的输出都和整图一致,所以它学到的不是「这块纹理长什么样」,而是「这块纹理属于什么」。DINO 代码默认用 8 个局部裁剪,局部裁剪分辨率低,所以多加几个并不贵。

3. 自蒸馏:老师是学生的影子

「蒸馏」原本指用一个训练好的大模型(老师)的输出当软标签去训练小模型(学生)。DINO 的老师不是预先训好的,而是在训练过程中从学生身上不断生成的:

每一步,老师的权重向学生的权重靠近一点点, 通常在 0.996 到 1 之间。这就是指数滑动平均(EMA),也叫动量编码器。学生的参数用梯度更新,老师的参数从不接收梯度。整个前向和损失如下图,点方块看细节。

随机增广 全局裁剪 ×2 局部裁剪 ×n 老师 gθtViT + 投影头 学生 gθsViT + 投影头 中心化 −c softmax(·/τt) softmax(·/τs) 交叉熵−Σ Pt log Ps EMA θt ← λθt + (1−λ)θs 老师这一侧没有梯度(stop-gradient) 两张虚线箭头以外的路径都是普通前向;损失只对学生反向传播

点一个方块。

为什么要一个 EMA 老师,而不是让学生直接和自己的另一个视图对齐?两个原因。第一,老师是学生历史上所有版本的加权平均,相当于一个免费的模型集成,论文里观察到整个训练过程中老师始终比学生好一点,于是学生总有一个「略强于自己」的目标可以追。第二,老师变化慢,目标稳定,不会出现学生追着自己的噪声跑的正反馈。拖动下面的 感受一下:学生的参数在噪声里抖,老师是它的平滑版本。

灰线是学生某一个参数随训练步数的轨迹(人造的:缓慢的趋势加噪声),主题色线是老师的同一个参数。λ = 0.9 时老师几乎贴着学生走,平滑作用弱;λ = 0.999 时老师拖后太多,学生追不上目标。DINO 用 0.996 并在训练中按余弦升到 1;DINOv3 直接用常数 0.999,因为它的训练步数多得多。

4. 防坍塌:中心化与锐化

老师和学生的输出都是 维向量经过 softmax 得到的分布()。没有负样本,怎么防止坍塌?论文把坍塌分成两种:

  1. 一个维度独大:所有图片的输出都是同一个独热向量。交叉熵为零,但什么都没学到。
  2. 均匀分布:所有图片的输出都是平的,同样交叉熵很小。

DINO 用两个相反的操作各堵一个洞。中心化在老师的 logits 上减去一个滑动平均 ,等于把「所有图片共有的那部分偏好」抹掉,于是没有哪一维能长期独大,但它本身会把分布推向均匀。锐化用很低的温度 让老师的输出变尖,推向独热。两者互相牵制,模型只能走中间那条路:每张图自己的分布很尖,但不同图片尖在不同的地方。

下面的部件用 个原型、4 张图模拟。「共享偏置」模拟训练中某一维开始独大的情形(所有图在第 3 维上的分数都被抬高)。看两个熵:单张图的平均熵越低说明每张图越「有主见」,平均分布的熵越高说明不同图片的主见越不一样。健康的状态是前者低、后者高。

4 张图各自的老师输出 Pt
4 张图的平均分布
单张图的平均熵
平均分布的熵
均匀分布的熵 ln 82.079

三个实验:① 关掉中心化,把 b 拉到 6:四张图全都指向第 3 维,两个熵都趋近 0,这是独热坍塌。② 开着中心化,把 τt 拉到 1:每张图的分布都变平,单张图的熵趋近 ln 8,这是均匀坍塌。③ 开着中心化、τt = 0.1、b 随便拉:b 完全被 c 吃掉,每张图依然尖,平均分布依然平。

这个机制有一个值得记住的性质:它完全不看 batch 里别的图片是谁,只用了一个历史平均 。所以 DINO 对 batch 大小不敏感,用 128 的 batch 也能训,这和对比学习形成鲜明对比。

5. 涌现:注意力图就是分割,特征直接能用

论文标题叫「Emerging Properties」,说的是训练目标里没要求、结果却自己出现的两个性质。

第一,[CLS] token 的注意力图就是一张前景分割图。 看最后一层各个注意力头里 [CLS] 对每个 patch 的权重,它们几乎只落在物体上,不同的头还会分到物体的不同部位。有监督训练的 ViT 和卷积网络都没有这么干净。这不难理解:学生要从一块局部裁剪推断整图,它必须学会「什么是这张图里的主体」。

DINO ViT-S/8 最后一层多个注意力头上 [CLS] 的注意力图,没有用过任何分割标注

图片来自 DINO 官方仓库(Apache-2.0)。官方还有一段视频,把注意力图逐帧画在视频上,分割随着镜头移动一直跟着物体走。

第二,特征不需要任何微调就能用。 把 ImageNet 训练集的图片全部过一遍冻结的 DINO,存下 [CLS] 特征;测试时取最近的 20 个邻居投票。这个什么都没训的 kNN 分类器就能拿到 78.3%。有监督 ViT 的特征做同样的事差得多。下表是官方给的数字(ImageNet 上的 kNN 和线性探测,骨干冻结):

模型参数kNN线性
ResNet-5023M67.575.3
ViT-S/1621M74.577.0
ViT-S/821M78.379.7
ViT-B/1685M76.178.2
ViT-B/885M77.480.1

两个趋势在这张表里已经露头,后面两代都在顺着它走:patch 越小越好(/8 比 /16 好,密集任务上差距更大),模型越大越好。消融实验还给出了三条结论:去掉 EMA 老师直接坍塌;去掉多裁剪掉 5 个点以上;中心化和锐化少任何一个都坍塌。

第三部分:iBOT 与 DINOv2:从「整张图」到「每一块」,从方法到数据

6. iBOT:给 patch 也上一堂蒸馏课

DINO 的损失只作用在 [CLS] token 上,整张图一个目标,各个 patch 的输出没有被直接监督。与此同时 NLP 那边的 BERT 靠「遮住一些词再预测」学得很好,图像上的对应物叫遮挡图像建模(masked image modeling,MIM)。BEiT 先用一个离线训好的离散 VAE 把 patch 变成「视觉词」,再让模型预测被遮 patch 的词 id;MAE 干脆直接回归像素。

iBOT 的想法是:不需要离线的分词器,老师就是分词器。 学生看到的全局视图里随机遮掉一部分 patch(用一个可学习的 [MASK] 向量替换),老师看到完整的图。在每个被遮的位置上,学生的 patch 输出要去匹配老师在同一位置的 patch 输出分布。老师随学生一起 EMA 更新,所以叫「在线分词器」。损失就是 DINO 的 [CLS] 损失加上这一项:

学生看到的(遮住的块换成 [MASK])
老师看到的(完整)

iBOT 用的是整块整块地遮(blockwise masking),比例在 10% 到 50% 之间随机。遮成块而不是撒点,是为了不能靠相邻像素插值蒙混过去。和 MAE 不同的是,这里预测的不是像素,而是老师给出的「这块属于哪个原型」的分布,所以学到的 patch 特征是语义的,不是纹理的。

iBOT 把 ImageNet 线性探测推到 82.3%,更重要的是它的 patch 特征在检测、分割这些密集任务上明显变好了。从此「[CLS] 上一个 DINO 损失 + patch 上一个 iBOT 损失」成了这个系列的固定搭配,DINOv2 和 DINOv3 都是在它之上做加法。

7. DINOv2:数据才是主角

DINOv2 论文的摘要说得很直白:现有的自监督方法只要在足够多、足够多样、经过筛选的数据上训练,就能给出通用特征。方法层面它几乎就是 iBOT,真正的新东西是一条不用标签的数据筛选流水线。

问题在于:互联网图片的分布极度偏斜。随便爬 12 亿张图,可能几千万张是自拍和表情包,而「某种蜥蜴」只有几百张。直接在上面训练,模型把算力都花在学自拍上。DINOv2 的流水线是:

  1. 去重:用拷贝检测模型(SSCD)的特征,把近似重复的图合并,顺便删掉和评测集重复的图。
  2. 用特征检索:用一个已经训好的 ViT-H/16 给所有图算特征。把若干个人工整理过的数据集(ImageNet-22k、Google Landmarks、各种细粒度数据集等,只用图不用标签)当作「种子」,对每张种子图去未筛选的池子里找最近的 个邻居(大数据集 ;小数据集则先把池子聚成 10 万个类,取种子落入的那些类)。
  3. 把检索到的图合起来,得到 LVD-142M,1.42 亿张。

下面的玩具复现这个思路:池子里有 10 个「概念」,大小极不均衡;种子集每个概念只有一张图。对比「随机抽」和「按种子检索」两种办法抽出来的 100 张图覆盖了什么。

灰点:未筛选的池子(1080 张);★:10 张种子图;主题色点:被选中的图。

选中的图里每个概念各有几张

随机抽样会原样复制池子的偏斜:三个大概念占掉八成,小概念经常一张都没有。检索则让每个概念拿到差不多 k 张,而且因为是从池子里拿的,多样性比种子集本身高得多。真实流水线里种子有几千万张,池子有 12 亿张,但逻辑就是这个。

8. DINOv2 的训练配方

有了数据,DINOv2 在 iBOT 的基础上做了一串看起来琐碎、合起来决定成败的改动。论文自己说「大多数技术贡献是为了让大规模训练更快更稳」。

  • 两个损失各用一个投影头。iBOT 让 [CLS] 和 patch 共用一个头,DINOv2 发现大模型上分开更好。
  • 用 Sinkhorn-Knopp 代替中心化。SwAV 的做法:对一个 batch 的老师输出做几轮行列交替归一化,直接把「每个原型分到的样本数要均衡」这个约束算出来,比 EMA 中心化更硬。
  • KoLeo 正则。要求一个 batch 里的特征在空间中铺开,见下面的部件。
  • 先低分辨率训,最后用高分辨率收尾。224 训完,最后一小段用 518 分辨率,比全程高分辨率便宜得多,效果接近。
  • ViT-g/14,11 亿参数。patch 大小从 16 降到 14,因为第 5 节说过 patch 越小密集任务越好,而 14 是算力允许的折中。
  • 工程:FlashAttention、把不同分辨率的裁剪打包成一个序列一起算(sequence packing)、FSDP 分片、随机深度(stochastic depth)0.4。
  • 蒸馏出一家小模型。只从头训最大的 ViT-g,然后把它当固定老师,用同一套 DINO + iBOT 损失(去掉掩码)训 ViT-S、ViT-B、ViT-L。蒸馏出来的小模型比从头自监督训练的同尺寸模型明显更好。

KoLeo 来自一篇做检索的论文(Sablayrolles 等,2019),名字是 Kozachenko-Leonenko 熵估计器的缩写。它只做一件事:让每个特征离它最近的邻居尽量远。

KoLeo 损失:

24 个单位向量(L2 归一化后的特征落在圆上)。每一步:每个点找自己最近的邻居,沿着远离它的方向走一小步,再投影回圆上。几十步之后它们自动铺成均匀的一圈,损失单调下降。DINOv2 用权重 0.1 把它加进总损失,作用是防止特征挤成几团,这对最近邻检索类任务特别重要;DINOv3 把它改成了在小的子组内计算的分布式版本。

结果(ImageNet,冻结骨干,官方数字):

模型参数kNN线性带寄存器 kNN带寄存器线性
ViT-S/14(蒸馏)21M79.081.179.180.9
ViT-B/14(蒸馏)86M82.184.582.084.6
ViT-L/14(蒸馏)300M83.586.383.886.7
ViT-g/141100M83.586.583.787.1

和 DINO 的表对比,ViT-S 这一档从 77.0 跳到 81.1,同样 2100 万参数。更要紧的是分类之外的任务:冻结的 DINOv2 特征上接一个线性层,就能做语义分割和单目深度估计,而且比当时的 OpenCLIP 好。「冻住骨干,到处可用」这件事从此成立了。

9. 寄存器:修掉背景里的「高范数怪点」

上表里的「带寄存器」来自半年后的一篇论文《Vision Transformers Need Registers》。作者在看 DINOv2 的注意力图时发现一个怪现象:图像背景里(天空、墙面这种没信息的区域)会零星出现几个 patch,输出范数是别的 patch 的 10 倍以上,它们在注意力图里是刺眼的亮点,会把分割、检测这类密集任务的结果弄脏。大模型、长训练才会出现,小模型没有。

探究下来,这些 token 携带的是全局信息而不是自己那块的局部信息:模型发现背景 patch 反正没用,就把它们征用为「草稿纸」存放全局计算的中间结果。解决办法简单得不像话:在输入序列里多加几个可学习的 token(寄存器),让模型有正经的草稿纸可用,输出时把它们丢掉。4 个寄存器就足够,背景的怪点消失,密集任务普遍提升。

示意图(合成数据,不是真实模型输出):16×16 个 patch 的输出范数,越深越大。中间的椭圆代表前景物体。没有寄存器时,背景里有几个 patch 的范数远高于其他;加入寄存器后,这些高范数被 4 个寄存器 token 接管,patch 本身的范数恢复平滑。真实的对比图可以看论文的图 1。

这件事的教训比修复本身更重要:全局指标(分类精度)看不出密集特征已经坏了。 带寄存器的 DINOv2 在 ImageNet 上只涨了零点几个点,但密集任务上的提升要大得多。DINOv3 遇到的核心问题,是同一个教训的放大版。

第四部分:DINOv3(2025):把自监督推到 70 亿参数

10. 规模:17 亿张图与 7B 参数

DINOv3 的出发点是把 DINOv2 的配方直接放大,看能不能像语言模型一样「越大越好」。它在三个维度上同时放大。

数据。 原始池子是 Instagram 公开帖子里约 170 亿张图(已经过平台内容审核)。筛选用了两条路:一条是层次化 k-means 聚类后做均衡采样(Vo 等,2024),保证每个视觉概念都有覆盖;另一条是 DINOv2 式的种子检索。两者合起来再加上 ImageNet 等公开数据集,得到 LVD-1689M,16.89 亿张。论文用 20 万步的短训练做了消融:只用原始数据,ImageNet kNN 为 80.1;聚类或检索单独用各有强项;合起来到 84.6。数据筛选本身就值 4 个多点。

模型。 下表是和 DINOv2 最大模型的对照:

DINOv2 ViT-g/14DINOv3 ViT-7B/16
参数11 亿67 亿
层数4040
宽度15364096
注意力头2432
FFNSwiGLUSwiGLU
patch1416
位置编码可学习轴向 RoPE
寄存器44
DINO 原型数128k256k

patch 从 14 回到 16 是因为 7B 模型算一个 token 太贵;位置编码换成 RoPE 并在训练时随机抖动坐标框,是为了让模型能在训练时没见过的分辨率和长宽比上工作,这对后面的高分辨率适配很关键。

训练。 和 DINOv2 的多段余弦学习率不同,DINOv3 把学习率、权重衰减、EMA 动量全部设成常数(学习率 0.0004,EMA 0.999,随机深度 0.4),训练 100 万步。理由很实际:这么大的模型没人能事先猜对该训多久,常数调度意味着只要下游指标还在涨就可以继续训,不必重开。前向用 bf16 和 8 位浮点矩阵乘,FSDP 分片,训练分辨率 256。

11. Gram anchoring:密集特征为什么会退化,怎么救

放大之后撞上的问题,就是第 9 节的教训的放大版。训练到 20 万步时 patch 特征很干净,到 100 万步时 ImageNet 等全局指标还在涨,但 patch 特征却变脏了:选一个 patch 看它和全图其他 patch 的余弦相似度,本来应该只亮起同一个物体,现在亮起一片噪声。分割、深度这些密集任务的指标随之下降。论文分析发现,这和寄存器修掉的高范数不是一回事:patch 的范数是稳定的,变化的是 [CLS] 和各个 patch 输出之间的相似度越来越高,也就是每个 patch 都越来越像整张图的摘要,越来越不像自己。

全局目标和局部一致性在长训练里是冲突的。DINOv3 的解法叫 Gram anchoring。Gram 矩阵就是一张图里所有 patch 特征两两的点积矩阵 ( 是 的 L2 归一化特征)。训练早期的老师(Gram 老师)的 Gram 矩阵是干净的,于是加一项损失,要求学生的 Gram 矩阵向它靠拢:

关键是它约束的是patch 之间的相似结构,不是特征本身。特征可以随便变(继续学全局语义),只要「哪些 patch 彼此相像」这张图不变。下面的部件在真实照片上用手工特征复现这个过程:先给每个 patch 算一个 4 维特征当作「早期老师」,再往里加噪声和一个全图共享的分量模拟退化,最后对退化后的特征做 Gram anchoring 的梯度下降。点图上任意一块,看它和全图的相似度图在三种状态下的样子。

Gram 老师(干净)
Gram 矩阵 196×196
长训练后的学生(退化)
L_Gram =
Gram anchoring 之后
L_Gram =

点一块 patch。

中间那列就是论文图 5 里「100 万步」的样子:相似度图上到处是噪点,Gram 矩阵里原本清晰的块状结构糊成一片。按下按钮,只用 Gram 损失做 40 步梯度下降,相似度结构就被拉回来了,而特征的「全局平均向量」几乎没动(见文字说明的余弦值),这正是「只约束结构、不约束特征」的意思。真实训练里 Gram 老师用 2 倍分辨率的图算特征再下采样,这样得到的 Gram 矩阵比直接算的更平滑,效果更好。

实际训练里,Gram anchoring 不是从头就开的,而是作为一个精修阶段:主训练 100 万步之后,再训一小段,损失是原来的 DINO + iBOT + KoLeo 再加上权重为 2 的 Gram 项;Gram 老师取训练早期的老师权重,每 1 万步更新一次,最多三次。效果是密集指标跳回来,全局指标几乎不损失(论文消融:ImageNet 线性 88.2 → 88.0,ADE20k 分割 mIoU 50.3 → 55.7,NYUv2 深度 RMSE 0.307 → 0.281)。论文还注意到一个现象:全局损失和 Gram 损失在训练曲线上彼此几乎独立,说明「学判别性的全局特征」和「保持局部一致性」本来就是两件事,可以分开管。

12. 一个老师,一家人:蒸馏、高分辨率适配、文本对齐

7B 模型训完之后,DINOv3 做了三件「事后」工作,让它从一个研究成果变成能用的产品。

高分辨率适配。 主训练在 256 分辨率上做。之后用一个很短的阶段混合多种分辨率(全局裁剪最大到 768)继续训,同时保留 Gram 项。得益于 RoPE,模型之后在训练时从没见过的 4096×4096 输入上依然给出稳定的特征图。这是它在高分辨率密集任务上领先的直接原因。

蒸馏成一个家族。 7B 模型没人部署得起。DINOv3 把它当固定老师,同时蒸馏出 ViT-S(21M)、S+(29M)、B(86M)、L(300M)、H+(840M)五个 ViT,以及 ConvNeXt T/S/B/L 四个卷积网络(方便在没有 Transformer 加速的设备上跑)。工程上用了一个「多学生」技巧:老师的前向只算一遍,结果分发给所有学生同时训。蒸馏出的 ViT-L 在很多任务上已经接近 7B 老师,是作者推荐的默认选择。

文本对齐。 冻住蒸馏出的 ViT-L,按 dino.txt 的方法训一个文本编码器,把 [CLS] 和 patch 输出都对齐到文本,于是有了零样本分类和开放词汇分割的能力。这条路和 CLIP 相反:CLIP 从图文对开始学视觉,DINOv3 先用纯图像学好视觉再接文本。

几个代表性数字(冻结骨干):ImageNet 线性 88.4;ADE20k 线性分割 55.9 mIoU,DINOv2 是 49.5;无监督物体发现(TokenCut)VOC07 上 66.1,DINOv2 是 55.6;三维关键点对应(NAVI)比 DINOv2 高 4.3 个点的召回。在骨干冻结的前提下,接一个检测头能到 COCO 66.1 mAP,接一个分割头能到 ADE20k 63.0 mIoU,都超过了专门微调的方案。同一套算法在 4.93 亿张卫星图上训出的 DINOv3-Sat,在树冠高度估计等遥感任务上也是最好的,说明这个配方不依赖自然图像的先验。

DINOv3 的密集特征:红叉标出的 patch 与全图其他 patch 的余弦相似度,输入分辨率 4096×4096

图片来自 DINOv3 官方仓库。对比第 11 节部件里退化状态的相似度图,可以直观感受 Gram anchoring 要保住的是什么。

第五部分:回到整体

13. 三代之间的规模曲线

把三代模型在 ImageNet 线性探测上的成绩按参数量画出来(横轴是对数刻度):

同样 2100 万参数的 ViT-S,DINO 是 77.0,DINOv2 是 81.1;DINOv3 论文对蒸馏出的小模型改用 ImageNet-ReaL 等指标报告,和这张图不直接可比,所以只画了 7B 主模型。每一代的曲线整体上移,是数据和配方的功劳;每一代曲线内部的上升,是模型规模的功劳。注意 DINOv2 的 ViT-L 和 ViT-g 几乎持平,DINOv3 的 ViT-L 也接近 7B:蒸馏出来的中等模型总能逼近老师,所以「训一个巨大的老师再蒸馏」比「直接训中等模型」划算。

回头看整个系列,可以用一句话概括每一代的贡献:

  • DINO 证明了自蒸馏 + 多裁剪这个极简框架能在 ViT 上学出带语义的特征,而且附赠分割。
  • iBOT 把监督信号从整张图扩展到每一个 patch,密集任务从此可用。
  • DINOv2 证明了方法已经够了,差的是数据:一条无标签的筛选流水线 + 一个 11 亿参数的老师 + 蒸馏,就得到了第一个冻结即用的视觉基础模型。
  • 寄存器和 Gram anchoring 则是同一类问题的两次修复:全局目标会在不知不觉中吞掉局部信息,分类精度看不出来,密集任务才会暴露。
  • DINOv3 在堵住这个漏洞之后,终于让「越大越好」在自监督视觉上成立,并把成果打包成一个从 2100 万到 67 亿参数的家族。

14. 对做几何的人意味着什么

本站读者大多关心特征匹配、定位和三维重建,DINO 系列和这些任务的关系值得单独说。

DINO 的特征是语义的、粗粒度的:每个 patch 16 像素见方,特征描述的是「这块是什么」,而不是「这块的亚像素位置在哪」。所以它不会取代 SuperPoint 这类关键点检测器,但在它们不擅长的地方很强:大视角变化、跨季节、跨模态、弱纹理。几个典型用法:

  • 粗到精匹配。RoMa 用冻结的 DINOv2 特征做粗匹配,再用自己训的精细模块做亚像素回归,在大视角变化下显著优于纯几何特征的方法。思路和 SuperGlue 用上下文增强描述子是一脉相承的,只是上下文换成了一个基础模型。
  • 视觉位置识别。AnyLoc 直接拿 DINOv2 的 patch 特征做 VLAD 聚合,不用在任何定位数据集上训练,跨环境的鲁棒性超过专门训练的模型。视觉定位流水线里的「先检索再精匹配」,检索这一步越来越多地交给 DINOv2。
  • 单目深度与前馈三维重建。Depth Anything 的编码器就是 DINOv2;VGGT 这类一次前向直接输出相机位姿、深度和点图的模型,把图片切成 patch 的那一步也用 DINOv2 初始化。基础模型提供「这是什么、大致在哪」的先验,后面的网络只需要学几何。
  • 跟踪与对应。DINO-Tracker 用 DINOv2 特征做长时视频点跟踪;DINOv3 论文自己也在三维关键点对应(NAVI、SPair)和视频分割跟踪(DAVIS)上做了评测,并且专门强调高分辨率下特征图依然干净,这正是 Gram anchoring 和高分辨率适配针对的场景。

一个实用的建议:做新任务时,先用冻结的 DINOv3 ViT-L(或者算力紧张时用 ViT-B 和 ConvNeXt)接一个线性层或一个小 DPT 头看看基线,很多时候这就够了。它的 patch 大小是 16,输入分辨率可以随意,特征图分辨率是输入的 1/16。需要更精细的对应时,再在上面叠一个精匹配模块。

延伸阅读

Comments