跳到主要内容

VGGT:Visual Geometry Grounded Transformer

论文:VGGT: Visual Geometry Grounded Transformer
作者:Jianyuan Wang, Minghao Chen, Nikita Karaev, Andrea Vedaldi, Christian Rupprecht, David Novotny
arXiv:2503.11651v1
本地文件:/root/other/paper/2503.11651v1.pdf
官方页面:arXiv 2503.11651
代码:facebookresearch/vggt

这篇论文解决什么问题

传统 3D 重建一般是长链条:

image matching
-> camera pose / intrinsics
-> triangulation
-> bundle adjustment
-> depth / dense reconstruction
-> fusion

DUSt3R 已经把问题推进了一步:它能从图像对直接预测 aligned pointmaps,但多图像场景还需要 pairwise 预测和 global alignment 后处理。

VGGT 再往前走一步:

直接把一组图像输入一个大型前馈 Transformer,一次性输出相机参数、depth map、point map 和 3D point tracks。

也就是说,它试图用一次 feed-forward 推理替代大量显式几何后处理。

VGGT 总体流程重绘示意图

图源说明:根据 Wang et al., VGGT 的模型与输出描述重绘,非论文原图。

一句话版本

VGGT 可以记成:

one / few / hundreds of images
-> large feed-forward transformer
-> cameras + depth maps + point maps + point tracks

它和 DUSt3R 的核心差别是:

DUSt3R:两图一对预测,再靠后处理对齐多图。
VGGT:多图一起输入,一次前向传播直接预测整组 3D 属性。

模型输入与输出

输入是一组观察同一场景的 RGB 图像:

(Ii)i=1N(I_i)_{i=1}^{N}

其中:

IiR3×H×WI_i\in\mathbb{R}^{3\times H\times W}

VGGT 的主网络记为:

ff

它把整组图像映射为每一帧的 3D 属性:

f((Ii)i=1N)=(gi,Di,Pi,Ti)i=1Nf((I_i)_{i=1}^{N}) = (\mathbf{g}_i,D_i,P_i,T_i)_{i=1}^{N}

其中:

输出形状 / 含义用途
gi\mathbf{g}_i相机参数,包含外参和内参camera pose estimation
DiD_idepth mapmulti-view depth
PiP_ipoint mapdense point cloud reconstruction
TiT_idense tracking features3D / 2D point tracking

相机参数采用:

g=[q,t,f]\mathbf{g}=[\mathbf{q},\mathbf{t},\mathbf{f}]

其中:

  • qR4\mathbf{q}\in\mathbb{R}^{4}:旋转 quaternion。
  • tR3\mathbf{t}\in\mathbb{R}^{3}:平移。
  • fR2\mathbf{f}\in\mathbb{R}^{2}:field of view / focal 相关参数。

论文假设 principal point 位于图像中心,这和很多 SfM 系统中的常见设定一致。

Coordinate Frame:为什么第一帧很重要

VGGT 和 DUSt3R 一样,把 point maps 定义在第一帧相机坐标系中。也就是说:

Pi(y)R3P_i(\mathbf{y})\in\mathbb{R}^3

不是表达在第 ii 个相机自己的坐标系,而是表达在第一帧的坐标系中。

第一帧相机被当作 world reference frame:

q1=[0,0,0,1]\mathbf{q}_1=[0,0,0,1] t1=[0,0,0]\mathbf{t}_1=[0,0,0]

这和你前面整理的 point-map / 多视角融合笔记可以直接对应:

阶段三:把每个局部 point map 变到同一个 world frame。
VGGT:网络直接把 point maps 预测到第一帧 frame。
⭐ VGGT 是不是也需要一个“全局坐标系”?

需要,但这个“全局”不是外部给定的真实世界坐标,而是由第一帧定义出来的规范坐标系。

如果把第一帧作为参考,那么所有相机和 point maps 都可以表达在第一帧坐标中:

Pi(1)P_i^{(1)}

这样模型输出之间可以直接比较和融合。

这类似于 DUSt3R 的 X2,1X^{2,1}:第二张图的点不是在第二相机坐标系,而是在第一相机坐标系。

区别是 DUSt3R 每次只处理图像对,而 VGGT 一次处理整组图像。

架构:Alternating-Attention Transformer

VGGT 不是一个手工写满几何规则的网络。论文强调它是一个大型 Transformer,只有很少的 3D inductive bias。

整体流程:

images
-> DINO patchify into image tokens
-> append camera tokens and register tokens
-> alternating frame-wise / global self-attention
-> prediction heads

VGGT Alternating-Attention 重绘示意图

图源说明:根据 Wang et al., VGGT 的 Alternating-Attention 描述重绘,非论文原图。

Frame-wise self-attention

Frame-wise attention 只在单张图像内部做 self-attention:

image i tokens attend to image i tokens

它负责让每张图内部的纹理、边缘、局部结构和语义上下文先组织起来。

Global self-attention

Global attention 把所有图像的 tokens 放在一起做 self-attention:

all image tokens attend to all image tokens

它负责跨视角交换信息,让不同图片之间建立几何关系。

论文默认使用:

L=24L=24

层 global / frame-wise attention。重要的是:VGGT 不使用 cross-attention layers,而是在 self-attention 的作用域上交替切换。

⭐ 为什么 Alternating-Attention 能处理多图关系?

如果只做 frame-wise attention,每张图像内部能理解得很好,但不同图像之间无法交换信息。

如果只做 global attention,所有 token 混在一起,计算和归一化都更重,而且模型可能更难稳定地区分“同一图内部结构”和“跨图几何关系”。

Alternating-Attention 的折中是:

frame-wise attention:先整理每张图自己的信息
global attention:再让所有图之间交换信息
frame-wise attention:回到每张图内细化
global attention:继续跨视角对齐

所以它不像 DUSt3R 那样显式处理图像对,也不像传统 SfM 那样先匹配再优化,而是让整个图像集合在 Transformer token 空间里反复交换信息。

Prediction Heads

VGGT 有多个输出头,对应不同 3D 属性。

VGGT Prediction Heads 重绘示意图

图源说明:根据 Wang et al., VGGT 的 prediction heads 描述重绘,非论文原图。

Camera head

每张图像有一个 camera token。经过 AA Transformer 后,输出 camera tokens:

t^ig\hat{\mathrm{t}}^{\mathbf{g}}_i

Camera head 用额外 self-attention 层和 linear layer 预测:

g^i\hat{\mathbf{g}}_i

也就是该图像的外参和内参。

Dense heads:depth 与 point map

输出 image tokens:

t^iI\hat{\mathrm{t}}^{I}_i

先通过 DPT layer 转成 dense feature map:

FiRC×H×WF_i\in\mathbb{R}^{C''\times H\times W}

再用卷积层预测:

Di,PiD_i,\quad P_i

也就是 depth map 和 point map。

论文还预测 depth / point map 的 aleatoric uncertainty:

ΣiD,ΣiP\Sigma_i^D,\quad \Sigma_i^P

它们在训练 loss 中作为不确定性权重,训练后也可以理解为模型对该像素预测的 confidence。

⭐ 为什么 dense 输出用 DPT + 3x3 卷积读出?

⭐ 为什么不是直接用 Transformer head 输出 depth 和 point map?

论文在 Dense Predictions 部分说:输出 image tokens t^iI\hat{t}^I_i 用来预测 dense outputs,包括 depth maps DiD_i、point maps PiP_i 和 tracking features TiT_i。更具体地说,t^iI\hat{t}^I_i 会先通过 DPT layer 转成 dense feature maps:

FiRC×H×WF_i\in\mathbb{R}^{C''\times H\times W}

然后每个 FiF_i 再通过 3×33\times3 convolutional layer 映射为对应的 depth map 和 point map:

Di,PiD_i,\quad P_i

同时,DPT head 也输出:

TiRC×H×WT_i\in\mathbb{R}^{C\times H\times W}

作为 tracking head 的输入。模型还预测 depth 和 point map 的 aleatoric uncertainty:

ΣiDR+H×W\Sigma_i^D\in\mathbb{R}_+^{H\times W}ΣiPR+H×W\Sigma_i^P\in\mathbb{R}_+^{H\times W}

这些 uncertainty maps 在 loss 中使用;训练后,它们和模型对预测的 confidence 成比例。

1. Transformer 已经完成主要几何推理

输入图像先被切成 patch tokens:

IitiII_i\rightarrow t_i^I

再加入:

  • camera token
  • register tokens
  • image patch tokens

这些 token 经过 VGGT 主干中交替的:

  • frame-wise attention
  • global attention

得到:

t^iI,t^ig\hat{t}_i^I,\quad \hat{t}_i^g

其中:

  • t^iI\hat{t}_i^I:图像空间相关的 tokens。
  • t^ig\hat{t}_i^g:相机相关的 token。

关键是:最后的卷积并不是从原始 RGB 直接猜深度。它接收到的特征已经经过大型 Transformer 的多视图全局推理。

换句话说,Transformer 已经负责解决困难部分:

  • 多视图对应。
  • 场景上下文。
  • 相机之间的关系。
  • 前后遮挡。
  • 物体结构先验。
  • 跨图像几何关系。

最后的卷积只是在做:

把已经包含几何信息的特征,读出成每个像素的数值。

2. Camera 为什么使用 Transformer head

Camera 是一组低维、整张图级别的参数,例如:

gi=(Ri,ti,Ki)g_i=(R_i,t_i,K_i)

它不是每个像素都有一个 camera。一张图只需要预测一组:

  • 旋转
  • 平移
  • 焦距或内参编码

因此 camera token 可以理解为一张图的“全局相机摘要”:

t^igRC\hat{t}_i^g\in\mathbb{R}^{C}

不过不同相机之间仍然需要相互比较。例如,相机 2 的姿态必须相对于第一台相机来定义,所以论文又用四层 self-attention,让所有输出 camera tokens 继续交互:

(t^1g,,t^Ng)4 self-attention layerslinear(g1,,gN)(\hat{t}_1^g,\ldots,\hat{t}_N^g) \rightarrow 4\ \text{self-attention layers} \rightarrow \text{linear} \rightarrow (g_1,\ldots,g_N)

这很合理,因为 camera prediction 是:

  • 图像级输出。
  • 低维输出。
  • 各相机之间高度相关。
  • 需要全局多视图关系。

3. Depth 和 Point-map 为什么不能直接从 token 输出

Transformer 输出的 image tokens 通常是 patch 级的。

假设输入大小:

518×518518\times518

patch size 为:

14×1414\times14

那么 token 网格大小大约是:

37×3737\times37

也就是说,主干输出类似:

t^iIR1369×C\hat{t}_i^I\in\mathbb{R}^{1369\times C}

但 depth map 需要:

DiR518×518D_i\in\mathbb{R}^{518\times518}

point map 需要:

PiR518×518×3P_i\in\mathbb{R}^{518\times518\times3}

两者分辨率相差很大:

37 x 37 -> 518 x 518

所以首先需要一个 dense decoder,将低分辨率 patch tokens 恢复为逐像素特征。这就是 DPT 的作用。

4. DPT 才是主要的 dense prediction head

论文里说的 DPT layer,不应简单理解为“只有一层”。DPT 本质上是一个稠密预测解码器,它完成类似:

多个层级的 Transformer tokens
-> 二维特征图
-> 多尺度融合
-> 逐步上采样
-> F_i

最终得到:

FiRC×H×WF_i\in\mathbb{R}^{C''\times H\times W}

此时,每个像素已经有一个 CC'' 维的几何特征:

Fi(:,v,u)RCF_i(:,v,u)\in\mathbb{R}^{C''}

它可能编码:

  • 该像素的局部表面。
  • 深度线索。
  • 三维位置。
  • 物体边界。
  • 跨视图对应。
  • 可见性。
  • 预测不确定性。

因此真正的架构不是:

Transformer token
-> 单个卷积
-> depth

而是:

多视图 Transformer tokens
-> DPT 多尺度 dense decoder
-> H x W 稠密几何特征
-> 3x3 卷积读出数值
-> depth / point map

VGGT 的官方接口也把 camera、depth 和 point map 作为独立分支调用。官方说明中还提到,由预测 camera 和 depth 反投影得到的点通常比直接 point-map branch 更准确。

5. 最后的 3x3 卷积只是在做“读出”

假设:

FiRC×H×WF_i\in\mathbb{R}^{C''\times H\times W}

depth head 可以大致理解为:

[Di,ΣiD]=Conv3×3D(Fi)[D_i,\Sigma_i^D]=\mathrm{Conv}_{3\times3}^{D}(F_i)

point head 可以大致理解为:

[Pi,ΣiP]=Conv3×3P(Fi)[P_i,\Sigma_i^P]=\mathrm{Conv}_{3\times3}^{P}(F_i)

对于某一个像素,卷积读取它周围 3×33\times3 范围内的 dense features,然后输出相应数值。

Depth 输出主要是:

Di(v,u)D_i(v,u)

Point-map 输出主要是:

Pi(v,u)=(Xi,Yi,Zi)P_i(v,u)=(X_i,Y_i,Z_i)

同时还预测相应不确定性。

此时困难的几何信息已经位于 FiF_i 中,最后一层只需要学习一个相对简单的映射:

geometry feature -> numeric geometry output

这类似于语义分割:

dense feature -> 1x1 / 3x3 conv -> class logits

并不需要再次使用一个庞大的 Transformer。

6. 为什么用 3x3 卷积,而不是线性层

对每个像素单独使用线性层,本质上等价于 1×11\times1 卷积:

y(v,u)=WF(v,u)+by(v,u)=WF(v,u)+b

3×33\times3 卷积还会读取附近像素:

y(v,u)=Δu,Δv=11WΔu,ΔvF(v+Δv,u+Δu)+by(v,u)= \sum_{\Delta u,\Delta v=-1}^{1} W_{\Delta u,\Delta v} F(v+\Delta v,u+\Delta u)+b

它提供了轻量级的局部空间归纳偏置。

这对 dense geometry 有好处:

  • 邻近像素通常位于同一表面。
  • 深度通常局部连续。
  • 表面边缘需要邻域信息。
  • Point-map 的局部方向需要保持协调。
  • 上采样产生的局部伪影可以进一步修正。

但不能误解为:

VGGT 主要依靠 3x3 卷积推理深度。

实际上,这个卷积的感受野虽然只有 3×33\times3 个 dense feature,但其中每个 feature 已经通过 Transformer 获得了全局、多视图信息。

因此:

Fi(v,u)F_i(v,u)

本身就可能包含来自其他图像和远距离区域的信息。

7. 为什么不用另一个 Transformer 输出逐像素 depth

当然可以设计成 Transformer decoder,例如为每个输出像素设置 query:

qv,uq_{v,u}

然后让它查询所有 image tokens:

q_{v,u} -> cross-attention -> D(v,u)

但这通常没有必要,而且代价很高。

如果有:

H×W=5182268000H\times W=518^2\approx268000

个像素 query,而 token 数又有数千甚至更多,逐像素 attention 的成本会非常大。

相反,DPT 使用:

  • patch-level Transformer reasoning。
  • 卷积式上采样。
  • 多尺度融合。
  • 局部卷积输出。

计算效率更高。

Depth 和 Point-map 都是规则二维网格:

H×WH\times W

卷积天然适合处理:

  • 邻域。
  • 边界。
  • 局部平滑。
  • 平移共享。
  • 任意位置使用相同输出规则。

Transformer 更擅长建立远距离和跨视图关系;卷积更适合将这些关系解码成规则 dense output。

VGGT 的设计可以概括为:

Transformer 负责全局关系,DPT / 卷积负责空间解码。

8. 为什么 Point-map 可以用卷积输出三维坐标

你可能会觉得:

(X, Y, Z) 是全局三维坐标,怎么可能通过局部卷积预测?

关键仍然是卷积输入不是局部 RGB,而是经过全局 Transformer 的特征。

设:

Fi(v,u)F_i(v,u)

其中可能已经编码了:

  • 该像素属于哪个物体。
  • 它与其他视图哪个位置对应。
  • 相机之间如何运动。
  • 当前帧相对于第一帧的位置。
  • 该点在第一相机坐标系下的大致位置。

那么卷积只需读出:

(X,Y,Z)=h(Fi 的局部邻域)(X,Y,Z)=h(F_i\ \text{的局部邻域})

卷积本身不需要独立完成三角化。

一个类比是语言模型:

Transformer hidden state
-> linear layer
-> vocabulary probabilities

最终词表可能有几十万个词,但并不意味着最后一个线性层完成了语言理解。语言理解已经发生在 hidden state 中。

同理:

VGGT dense geometry feature
-> 3x3 conv
-> X, Y, Z

三维推理已经主要发生在 Transformer 和 DPT features 中。

9. Camera 与 Point-map 分支为什么采用不同 token

两类输出的空间性质不同。

Camera 是一张图一组参数:

gig_i

属于全局、低维输出,因此使用:

t^ig\hat{t}_i^g

也就是 camera token。

Depth / Point-map 是每个像素都有一个输出:

Di(v,u),Pi(v,u)D_i(v,u),\quad P_i(v,u)

属于空间密集、高维输出,因此使用:

t^iI\hat{t}_i^I

即 image patch tokens。

可以类比为:

任务特征来源
图像分类CLS token
相机姿态camera token
语义分割image patch tokens
深度估计image patch tokens
point mapimage patch tokens

不是所有输出都应该由同一种 token 预测。

Tracking head

VGGT 输出 dense tracking features:

TiRC×H×WT_i\in\mathbb{R}^{C\times H\times W}

然后用 CoTracker2 风格的 tracking module:

query point
-> sample query feature
-> correlate with other frames
-> attention refinement
-> predict corresponding 2D points

这使 VGGT 不只做静态重建,也能支持 point tracking。

Over-complete Predictions:为什么同时预测这么多东西

从几何上看,VGGT 的输出有冗余。

例如,如果已经有 point map:

PiP_i

理论上可以通过 PnP 等方法反推出 camera:

gi\mathbf{g}_i

如果已经有 camera 和 depth:

gi,Di\mathbf{g}_i,\quad D_i

也可以通过反投影得到 point map:

PiP_i

但论文发现:训练时显式预测 camera、depth、point map、tracks,反而能提升整体性能。

⭐ 为什么冗余输出反而有帮助?

这些任务之间不是孤立的:

  • camera pose 决定不同图像之间如何对齐。
  • depth map 决定每个像素沿 ray 的距离。
  • point map 是 depth 和 camera 的 3D 表达。
  • tracks 表示跨视角的点对应关系。

如果模型只学其中一个任务,监督信号比较单一。

多任务训练相当于从多个角度约束同一个 3D 场景:

camera loss 约束视角关系
depth loss 约束每个像素的深度
point-map loss 约束全局 3D 位置
tracking loss 约束跨图对应

所以“冗余”不是浪费,而是让模型更稳定地学习共享的 3D 几何结构。

训练目标

VGGT 用多任务 loss 端到端训练:

L=Lcamera+Ldepth+Lpmap+λLtrack\mathcal{L} = \mathcal{L}_{\text{camera}} + \mathcal{L}_{\text{depth}} + \mathcal{L}_{\text{pmap}} + \lambda\mathcal{L}_{\text{track}}

其中论文设置:

λ=0.05\lambda=0.05

各项含义:

Loss监督对象直觉
Lcamera\mathcal{L}_{camera}相机参数让外参和内参正确
Ldepth\mathcal{L}_{depth}depth map让每像素深度正确
Lpmap\mathcal{L}_{pmap}point map让每像素 3D 点正确
Ltrack\mathcal{L}_{track}point tracks让跨图对应正确

Depth 和 point-map loss 中还包含 gradient-based term,鼓励局部几何变化一致,而不只是逐点数值接近。

Ground Truth Coordinate Normalization

3D 重建存在规范自由度:把整个场景一起旋转、平移或缩放,图像观测本身可能不变。

VGGT 通过两步消除歧义:

  1. 把所有量表达在第一帧相机坐标系。
  2. 用 point map 中所有 3D 点到原点的平均欧氏距离做尺度归一化。

也就是说,训练数据被规范化到一个固定尺度和固定参考系下,模型学习输出这个规范化版本。

和 DUSt3R 的关系

维度DUSt3RVGGT
输入图像对一张、几张、上百张图像
多图处理pairwise + global alignment整组图像一次输入
主要输出aligned pointmaps + confidencecameras、depth、pointmaps、tracks
后处理多图通常需要优化对齐直接输出可用结果,可选 BA
架构pairwise TransformerAlternating-Attention Transformer
坐标系图像对中第一张为参考输入序列第一张为参考

最关键的区别是:DUSt3R 在两图 pairwise 几何上很强,VGGT 则把多图关系直接放进一个大 Transformer 里建模。

⭐ VGGT 是不是完全替代传统 Bundle Adjustment?

不完全。

VGGT 的主要卖点是:不用后处理也能得到很强的 feed-forward 预测。

但论文也说明,如果再接 Bundle Adjustment,VGGT 结果还能继续提升。

所以更准确的理解是:

VGGT 把传统 BA 从“必须依赖的核心流程”
变成了“可选的精修步骤”。

这和传统 SfM 不同。传统 SfM 中 BA 往往是保证结果能用的关键步骤;VGGT 中,网络本身已经输出 cameras、depth 和 point maps,BA 只是进一步提高一致性和精度。

输出可以用来干什么

输出可以做什么
camerascamera pose estimation、COLMAP 导出、后续 BA
depth mapsmulti-view depth estimation、depth-based point cloud
point mapsdense 3D reconstruction、point cloud fusion
tracking features / trackspoint tracking、dynamic tracking 下游任务
pretrained backbonenovel view synthesis、非刚性 tracking 等下游任务

官方代码中也支持把预测结果导出为 COLMAP 格式,进一步接 Gaussian Splatting 或其他 NeRF / 3DGS 工具链。

单视图能力

一个有意思的点是:VGGT 虽然是为多视图几何设计的,但官方说明它在 single-view reconstruction 上也有较好表现。

这说明 Transformer 从大规模 3D 标注数据中学到了很强的通用几何先验。单张图像没有多视角约束,理论上深度和遮挡区域存在歧义,但模型可以根据语义、纹理和形状先验给出合理猜测。

要注意:这不等于单图可以恢复唯一真实 3D。它只是说明模型学到的 prior 很强。

局限与成本

  1. 输入图像越多,global attention 的显存和计算量越大。
  2. 第一帧作为参考系,因此输入顺序中第一张图具有特殊角色。
  3. 模型大,论文默认约 1.2B 参数。
  4. 没有显式几何优化时,输出仍可能有局部不一致;接 BA 可进一步修正。
  5. 单视图重建依赖先验,遮挡背面和尺度仍有歧义。

官方仓库在 2026 年 5 月更新中提到修复了中间张量冗余保留的问题,同样显存预算下可处理更多输入帧;这也侧面说明 VGGT 的实际使用很受显存管理影响。

和我的 point-map 学习路线怎么连接

你前面的路线是:

camera ray
-> depth
-> camera-space point map
-> SE(3)
-> multi-view fusion

VGGT 则像是把这些传统步骤压进了一个模型:

images
-> transformer
-> camera parameters
-> depth maps
-> point maps in first camera frame
-> point tracks

因此,读 VGGT 时最值得抓住三个问题:

  1. 第一帧坐标系为什么可以作为全局参考?
  2. depth、camera、point map 三者如何互相约束?
  3. frame-wise / global attention 如何替代显式 pairwise matching 和 global alignment?

速记

VGGT 的核心是:

VGGT = 多图输入的大型几何 Transformer
= 一次前向传播输出 camera / depth / pointmap / track
= 用多任务监督学习共享 3D 几何

如果 DUSt3R 是:

image pair -> aligned pointmaps

那么 VGGT 更像:

image set -> complete geometric attributes

这就是它相对 DUSt3R 最重要的升级。