目录

  1. 核心架构对比
  2. 排列等变性实现机制
  3. 关键技术差异
  4. 代码实现对比
  5. 为什么VGGT没有Pi3的核心优势
  6. 实际应用场景对比
  7. 总结

核心架构对比

VGGT (Visual Geometry Grounded Transformer)

论文来源: Meta AI & University of Oxford (2025)

GitHub: https://github.com/facebookresearch/vggt

架构特点

输入图像 (1~数百张)

↓  
DINO特征提取(Patchify)  
↓  
添加Camera Token + Register Token  
↓  
交替注意力机制(Alternating-Attention)  
帧内自注意力(Frame-wise Self-Attention)  
全局自注意力(Global Self-Attention)  # Pi3相比VGGT的核心优势深度分析

## 📌 核心论点

**Pi3通过显式的几何设计和理论保证的等变性,在多个关键维度上超越了VGGT的隐式学习范式。**

---

## 🎯 执行摘要

VGGT代表了"规模驱动"的3D重建范式:用1.2B参数和17+数据集让网络隐式学习几何关系。而Pi3代表了"几何驱动"的范式:通过显式设计保证等变性和几何一致性。

**关键发现**:
1. VGGT的第一帧依赖破坏了完全等变性
2. 缺乏显式位置编码导致空间关系模糊
3. 直接预测缺乏几何约束
4. 高昂的训练成本和资源需求
5. 应用场景受限

**Pi3的突破**:
1. ✅ 完全等变性(所有帧平等)
2. ✅ RoPE精确位置编码
3. ✅ 强制几何约束(局部→全局)
4. ✅ 轻量高效
5. ✅ 灵活应用(增量、多序列)

---

## 📊 七大核心优势

### 优势1: 完全排列等变性 vs 部分等变性

#### VGGT的致命缺陷:第一帧特殊化

```python
# VGGT的设计
class VGGT:
    def __init__(self):
        self.camera_token_first = nn.Parameter(...)  # 第一帧专用
        self.camera_token_other = nn.Parameter(...)  # 其他帧共享
    
    def forward(self, images):
        # 第一帧固定为恒等变换
        cameras[0] = Identity()  # q=[0,0,0,1], t=[0,0,0]
        
        # 所有预测在第一帧坐标系
        for i in range(1, N):
            points[i] = predict_in_frame0_coords(images[i])

问题1: 破坏完全等变性

测试1:
输入: [A, B, C]
输出: points_in_A_coords = [[0,0,0], [1,0,0], [0,1,0]]

测试2:
输入: [B, A, C]  # 改变顺序
输出: points_in_B_coords = [[1,0,0], [0,0,0], [0,1,0]]

结论: 输出坐标系改变!不是真正的等变!

问题2: 第一帧质量依赖

# 场景1: 第一帧清晰
images = [clear_image, blurry_image, normal_image]
result1 = VGGT(images)  # 高质量重建

# 场景2: 第一帧模糊
images = [blurry_image, clear_image, normal_image]
result2 = VGGT(images)  # 质量下降!

# 问题: 第一帧的选择成为关键超参数

问题3: 多序列融合困难

# 序列1
seq1 = [A1, A2, A3]
points1 = VGGT(seq1)  # 在A1坐标系

# 序列2
seq2 = [B1, B2, B3]
points2 = VGGT(seq2)  # 在B1坐标系

# 融合需要额外对齐
transform = estimate_transform(points1, points2)  # 复杂且不准确
merged = transform @ points2
Pi3的解决方案:所有帧平等
# Pi3的设计
class Pi3:
    def forward(self, images):
        # 所有帧平等对待
        for i in range(N):
            # 每帧预测局部坐标
            local_points[i] = predict_local(images[i])
            # 每帧预测相机位姿
            camera_poses[i] = predict_camera(images[i])
        
        # 统一到全局坐标系
        global_points = camera_poses @ local_points
        return global_points

优势1: 完全等变性

测试1:
输入: [A, B, C]
输出: points_global = [[0,0,0], [1,0,0], [0,1,0]]

测试2:
输入: [B, A, C]  # 改变顺序
输出: points_global = [[0,0,0], [1,0,0], [0,1,0]]  # 相同!

结论: 真正的等变性!✅

优势2: 无质量依赖

# 任意顺序都可以
images = [blurry, clear, normal]
result1 = Pi3(images)  # 高质量

images = [clear, blurry, normal]
result2 = Pi3(images)  # 同样高质量

# 网络自动处理,无需人工选择

优势3: 自然融合

# 所有序列在统一坐标系
seq1 = [A1, A2, A3]
points1 = Pi3(seq1)  # 全局坐标系

seq2 = [B1, B2, B3]
points2 = Pi3(seq2)  # 同一全局坐标系

# 直接融合,无需对齐
merged = concat([points1, points2])  # 简单且准确

优势2: 精确位置编码 vs 隐式位置信息

VGGT的缺陷:依赖DINO隐含信息
# VGGT
tokens = DINO(images)  # 依赖预训练的位置信息
# 没有额外的位置编码
output = transformer(tokens)

问题1: 位置信息不精确

  • DINO是为分类任务设计的,不是为3D重建优化
  • 位置信息是隐含的,不够精确
  • 缺乏像素级的空间关系

问题2: 分辨率泛化差

# 训练: 518×518
model.train(images_518)

# 测试: 1024×1024
model.test(images_1024)  # 位置信息可能失效

# 测试: 256×256
model.test(images_256)  # 同样可能失效

问题3: 相对位置关系模糊

Token A at (10, 20)
Token B at (15, 25)

VGGT: 无法明确知道A和B的相对位置
      依赖网络隐式学习
Pi3的优势:RoPE2D精确编码
# Pi3
class RoPE2D:
    def __init__(self, freq=100):
        self.freq = freq
    
    def forward(self, q, xpos):
        # xpos: (B, N, 2) - 精确的2D坐标
        theta = xpos * self.freq
        
        # 旋转编码
        cos_theta = torch.cos(theta)
        sin_theta = torch.sin(theta)
        
        # 应用旋转
        q_rotated = rotate(q, cos_theta, sin_theta)
        return q_rotated

优势1: 精确的相对位置

Token A at (10, 20)
Token B at (15, 25)

RoPE编码:
- 相对距离 = sqrt((15-10)^2 + (25-20)^2) = 7.07
- 相对角度 = atan2(25-20, 15-10) = 45°
- 注意力权重 ∝ exp(-distance)

精确且可解释!

优势2: 分辨率无关

# 训练: 512×512
model.train(images_512)

# 测试: 1024×1024
model.test(images_1024)  # RoPE自动适应 ✅

# 测试: 256×256
model.test(images_256)  # 同样适应 ✅

# 原因: RoPE基于相对位置,不依赖绝对尺寸

优势3: 保持等变性

原始: [A, B, C]
相对位置: A-B=1, B-C=1, A-C=2

排列后: [B, A, C]
相对位置: B-A=-1, A-C=1, B-C=2

RoPE编码的是相对位置差,排列后相对关系保持不变 ✅

优势3: 强制几何约束 vs 直接预测

VGGT的问题:缺乏几何约束
# VGGT直接预测
point_map = DPT_head(features)  # 直接预测3D点
depth_map = DPT_head(features)  # 独立预测深度
camera = camera_head(features)  # 独立预测相机

# 问题: 三者可能不一致
# 理论上应该满足: point_map = unproject(depth_map, camera)
# 但实际预测可能不满足

问题1: 冗余预测不一致

# VGGT的预测
point_pred = [1.0, 2.0, 3.0]
depth_pred = 3.5
camera_pred = [R, t, K]

# 检查一致性
point_from_depth = unproject(depth_pred, camera_pred)
# point_from_depth = [1.1, 2.1, 3.5]  # 不一致!

# 论文承认: "在推理时组合深度和相机参数更准确"
# 这暴露了预测不一致的问题

问题2: 缺乏多视图约束

# 每个视图独立预测
for i in range(N):
    points[i] = predict(view[i])  # 独立预测

# 没有显式的多视图几何约束
# 依赖网络隐式学习一致性

问题3: 难以融合多视图

# VGGT需要后处理融合
points_1 = predict(view_1)  # 在frame1坐标系
points_2 = predict(view_2)  # 在frame1坐标系

# 如何融合?需要额外的对齐和融合算法
merged = align_and_merge(points_1, points_2)
Pi3的优势:强制几何约束
# Pi3的设计
class Pi3:
    def forward(self, images):
        # 1. 预测局部坐标 (相机坐标系)
        local_points = predict_local(images)  # (x, y, z) in camera coords

        # 2. 预测相机位姿
        camera_poses = predict_camera(images)  # 4×4 变换矩阵

        # 3. 几何变换到全局
        global_points = camera_poses @ homogenize(local_points)

        # 保证: 几何关系严格满足
        return global_points

优势1: 强制几何约束

# Pi3的预测
local_point = [1.0, 2.0, 3.0]
camera_pose = [[R], [t]]  # 4×4矩阵

# 变换到全局
global_point = camera_pose @ homogenize(local_point)

# 保证: 几何关系严格满足
# P_global = R @ P_local + t
# 不存在不一致的问题 ✅

优势2: 多视图自然融合

# 所有视图的点都在统一的全局坐标系
points_1 = camera_1 @ local_1
points_2 = camera_2 @ local_2

# 自动对齐,无需额外处理
merged = concat([points_1, points_2])  # 简单且准确

优势3: 符合多视图几何原理

局部预测 → 相机坐标系 (单视图几何)
    ↓
相机位姿 → 外参矩阵 (多视图几何)
    ↓
全局变换 → 世界坐标系 (场景重建)

优势4: 统一架构 vs 两种注意力

VGGT的问题:交替注意力不对称
# VGGT伪代码
for layer_idx in range(24):
    if layer_idx % 2 == 0:
        # 帧内自注意力 (不同的网络模块)
        for i in range(N):
            tokens[i] = frame_wise_attention(tokens[i])
    else:
        # 全局自注意力 (不同的网络模块)
        all_tokens = concat(tokens)
        all_tokens = global_attention(all_tokens)

问题1: 两种注意力层不对称

  • 帧内层和全局层是不同的网络模块
  • 参数不共享,增加模型复杂度
  • 难以保证两种层的行为一致性

问题2: 帧内层的信息瓶颈

# 帧内层: 每帧独立
tokens[0] = attention(tokens[0])  # 只看到view 0
tokens[1] = attention(tokens[1])  # 只看到view 1

# 信息无法跨视图流动
# 依赖下一个全局层才能交互

问题3: 全局层的计算复杂度

# 全局层: 所有token混合
all_tokens = concat([tokens[0], ..., tokens[N-1]])
# 形状: (N*K, C) - 如果N=100, K=1024, 则100K个token

# 自注意力复杂度: O((N*K)^2)
# 当N很大时,计算量爆炸
Pi3的优势:统一架构
# Pi3
for i in range(len(self.decoder)):
    if i % 2 == 0:
        # 偶数层: 帧内独立
        hidden = hidden.reshape(B*N, hw, -1)
    else:
        # 奇数层: 跨帧交互
        hidden = hidden.reshape(B, N*hw, -1)

    # 所有层使用相同的BlockRope
    hidden = same_attention_block(hidden, xpos=pos)

优势1: 统一的注意力层

  • 所有层使用相同的BlockRope
  • 参数共享,模型更简洁
  • 行为一致性有保证

优势2: 灵活的信息流动

# 偶数层: (B*N, hw, -1)
# 每个视图内部充分交互

# 奇数层: (B, N*hw, -1)
# 所有视图的所有token混合
# 信息流动更自由

优势3: 计算效率

  • 通过reshape控制注意力范围
  • 可以根据需要调整交替频率
  • 更容易优化和并行化

优势5: 轻量高效 vs 大规模依赖

VGGT的成本
- 参数量: 1.2B
- 训练数据: 17+ 数据集
- 计算资源: 64×A100 GPU
- 训练时间: 9 天

问题1: 高昂的训练成本

  • 需要大量计算资源
  • 难以复现和微调
  • 不适合资源受限的场景

问题2: 数据偏差风险

# 如果训练数据主要是室内场景
model.train(indoor_datasets)

# 在室外场景可能表现不佳
model.test(outdoor_scene)  # 泛化能力受限

问题3: 隐式学习的不可控性

  • 依赖网络从数据中隐式学习几何关系
  • 缺乏显式的几何约束
  • 难以诊断和修复错误
Pi3的优势:几何先验
# Pi3的几何先验
# 1. 局部坐标系 (单视图几何)
local_points = predict_local(image)

# 2. 相机位姿 (多视图几何)
camera_pose = predict_camera(image)

# 3. 几何变换 (刚体变换)
global_points = camera_pose @ local_points

优势1: 更少的数据需求

  • 几何约束减少了需要学习的自由度
  • 可以在较小数据集上训练

优势2: 更好的泛化能力

  • 几何原理是通用的
  • 不依赖特定场景的数据分布

优势3: 可解释性和可控性

  • 每个组件有明确的几何意义
  • 容易诊断和改进

优势6: 理论保证 vs 经验验证

VGGT的隐式等变性
# VGGT
# 全局自注意力是等变的 (理论上)
output = self_attention(input)

# 但是:
# 1. 第一帧特殊化破坏了完全等变性
# 2. 没有显式的等变性验证
# 3. 依赖网络学习等变行为

问题

  • ❌ 第一帧不参与排列 → 不是完全等变
  • ❌ 没有理论保证 → 依赖经验验证
  • ❌ 难以证明 → 黑盒行为
Pi3的显式等变性
# Pi3的等变性证明

# 偶数层: 独立处理
f_even([x1, x2, ..., xN]) = [f(x1), f(x2), ..., f(xN)]
# 排列等变: ✓

# 奇数层: 自注意力
f_odd(π(X)) = π(f_odd(X))
# 自注意力等变: ✓

# 组合: f = f_odd ∘ f_even ∘ ... ∘ f_odd ∘ f_even
# 等变函数的组合仍然等变: ✓

优势

  • ✅ 数学上可证明的等变性
  • ✅ 所有帧平等对待
  • ✅ 不依赖网络学习等变行为

优势7: 应用灵活性 vs 受限场景

VGGT的限制

限制1: 第一帧选择问题

# 用户必须决定哪一帧作为参考
results = VGGT([frame_0, frame_1, ..., frame_N])
# frame_0 的质量影响整体结果

限制2: 增量重建困难

# 场景1: 重建前3帧
result_1 = VGGT([A, B, C])  # A是参考帧

# 场景2: 添加第4帧
result_2 = VGGT([A, B, C, D])  # 需要重新计算所有

# 无法增量更新

限制3: 多序列融合复杂

# 序列1
points_1 = VGGT([A, B, C])  # 在A坐标系

# 序列2
points_2 = VGGT([D, E, F])  # 在D坐标系

# 融合需要额外对齐
merged = align(points_1, points_2)
Pi3的灵活性

灵活性1: 无需选择参考帧

# 任意顺序都可以
result_1 = Pi3([A, B, C])
result_2 = Pi3([B, A, C])
result_3 = Pi3([C, B, A])
# 结果在同一全局坐标系 ✅

灵活性2: 支持增量重建

# 初始重建
result_1 = Pi3([A, B, C])

# 添加新帧 (可以只计算新帧)
local_D = predict_local(D)
camera_D = predict_camera(D)
points_D = camera_D @ local_D

# 增量更新
result_2 = merge(result_1, points_D)

灵活性3: 自然的多序列融合

# 所有序列在统一坐标系
points_1 = Pi3([A, B, C])
points_2 = Pi3([D, E, F])

# 直接融合,无需对齐
merged = concat([points_1, points_2])

📊 完整对比表

维度 VGGT Pi3 优势
第一帧依赖 第一帧特殊化 所有帧平等 Pi3 ✅
位置编码 无显式编码 RoPE2D Pi3 ✅
几何一致性 直接预测 局部+变换 Pi3 ✅
交替机制 两种注意力层 统一注意力+reshape Pi3 ✅
参数量 1.2B 更小 Pi3 ✅
训练资源 64×A100, 9天 更少 Pi3 ✅
等变性保证 隐式 (除第一帧) 显式 (所有帧) Pi3 ✅
应用灵活性 受限于第一帧 完全灵活 Pi3 ✅

🎯 应用场景对比

场景 VGGT 挑战 Pi3 优势
大规模重建 第一帧选择,分批对齐 增量处理,统一坐标系
实时 SLAM 第一帧固定,累积误差 动态参考,灵活变换
多相机系统 多坐标系对齐 自动统一坐标系
视频重建 滑动窗口对齐 流式处理,自动对齐
稀疏视图 模型过大 轻量高效

💡 核心洞察

为什么 Pi3 更优?

1. 哲学层面

  • VGGT: “用足够大的模型和足够多的数据,让网络自己学习”

    • 优点: 简单,依赖规模
    • 缺点: 成本高,不可控,缺乏理论保证
  • Pi3: “显式设计几何约束,让网络学习更容易”

    • 优点: 高效,可控,有理论保证
    • 缺点: 需要更多设计思考

2. 工程层面

VGGT的工程挑战:

# 1. 第一帧选择
best_frame = select_best_reference(frames)

# 2. 坐标系对齐
if reference_changed:
    points = transform_to_new_reference(points)

# 3. 多序列融合
merged = complex_alignment_and_fusion(seq1, seq2)

Pi3的工程简洁性:

# 1. 无需选择参考帧
results = Pi3(frames)

# 2. 统一坐标系
# 所有输出自动对齐

# 3. 简单融合
merged = concat([results1, results2])

3. 科学层面

  • VGGT: 经验驱动 (Empirical)

    • 依赖大规模实验验证
    • 缺乏理论分析
    • 黑盒行为
  • Pi3: 理论驱动 (Principled)

    • 基于多视图几何理论
    • 可证明的等变性
    • 可解释的行为

🏆 最终结论

为什么选择 Pi3?

7 个核心优势

  1. 完全等变 - 所有帧平等,无特殊帧
  2. 精确位置编码 - RoPE 提供精确相对位置
  3. 强制几何约束 - 局部+变换保证一致性
  4. 高效架构 - 统一注意力,参数共享
  5. 轻量高效 - 更少资源需求
  6. 理论保证 - 数学可证明
  7. 应用灵活 - 支持增量和多序列

VGGT 的优势

仅在于:

  • 大规模数据驱动的泛化能力
  • 多任务联合学习
  • 端到端的简洁性

技术债务对比

技术债务 VGGT Pi3
第一帧选择 需要额外逻辑 无需考虑
坐标系对齐 多序列需要对齐 自动统一
增量更新 需要重新计算 原生支持
分辨率泛化 可能失效 RoPE 自适应
理论验证 依赖实验 数学证明

📚 参考资源

  1. VGGT 论文: “VGGT: Visual Geometry Grounded Transformer” (Meta AI & Oxford, 2025)
  2. Pi3 代码: 排列等变 3D 重建
  3. 多视图几何: 经典理论基础
  4. 等变神经网络: 理论保证

文档版本: 2.0
创建时间: 2025
用途: 深入分析 Pi3 相对于 VGGT 的核心优势

多任务预测头
Camera Head →\rightarrow 相机参数(内外参)
DPT Head →\rightarrow 深度图
DPT Head →\rightarrow 点云图
CoTracker2 →\rightarrow 点追踪特征


# 核心设计理念:

- 最小3D归纳偏置: 除了交替注意力外, 几乎没有特殊的3D结构设计  
- 大规模数据驱动:在17+个数据集上训练,总参数量约1.2B  
- 单次前向推理: 无需后处理优化即可获得高质量结果  
- 多任务联合学习:同时预测相机、深度、点云、追踪特征

# Pi3 (Permutation-Invariant 3D Reconstruction)

# 论文来源:本项目

GitHub: https://github.com/cvlab-kaist/Pi3

# 架构特点

```txt
输入图像(B,N,3,H,W)  
↓  
DINOv2编码器(独立处理每张图)  
↓  
添加Register Token  
↓  
交替张量重塑  $+$  RoPE位置编码  
偶数层:  $(\mathsf{B}^{*}\mathsf{N},$  hwo dim)-帧内独立处理奇数层:(B,N\*hw,dim)-跨帧全局交互  
↓  
多任务解码器  
Point Decoder  $\rightarrow$  局部3D点Conf Decoder  $\rightarrow$  置信度Camera Decoder  $\rightarrow$  相机位姿  
↓  
全局坐标变换points  $=$  camera_poses@local_points

核心设计理念:

  • 显式排列等变性: 通过交替重塑保证输入顺序不影响输出
  • RoPE位置编码:使用旋转位置编码保持相对位置信息
  • 局部到全局:先预测局部坐标,再通过相机位姿变换到全局
  • 轻量级设计:相比VGGT更注重效率和等变性保证

排列等变性实现机制

VGGT的排列等变性

实现方式

VGGT通过交替注意力(Alternating-Attention)实现排列等变性:

VGGT伪代码  
for layer in range(24):  
    if layer_type == "frame_wise": # 帧内自注意力:每帧独立处理  
    for i in range(N):
tokens[i] = selfattention(tokens[i]) # 形状:  $(K, C)$  else: # 全局自注意力:所有帧联合处理 all_tokens = concat(tokens) # 形状:  $(N*K, C)$  all_tokens = selfattention(all_tokens)

等变性保证

  1. 帧内层: 每帧独立处理 →\rightarrow 排列不影响单帧结果
  2. 全局层: 标准自注意力对输入顺序具有排列等变性

。注意力权重: softmax(Q @ K^T) @ V
。这是对称操作,输入顺序改变时输出也相应改变

特殊处理:

  • 第一帧特殊化: 使用不同的Camera Token和Register Token
  • 坐标系锚定: 所有预测都在第一帧坐标系下
  • 第一帧固定: q1=[0,0,0,1],t1=[0,0,0]q1 = [0,0,0,1], t1 = [0,0,0]q1=[0,0,0,1],t1=[0,0,0] (恒等变换)

数学表达

设输入为 (I1,I2,…,IN)\left(I_{1}, I_{2}, \ldots, I_{N}\right)(I1,I2,,IN) ,排列操作为 π\piπ

f(π(I2,…,IN))=π(f(I2,…,IN)) f \left(\pi \left(I _ {2}, \dots , I _ {N}\right)\right) = \pi \left(f \left(I _ {2}, \dots , I _ {N}\right)\right) f(π(I2,,IN))=π(f(I2,,IN))

注意: 第一帧 I1I_{1}I1 不参与排列, 始终作为参考帧。

Pi3的排列等变性

实现方式

Pi3通过交替张量重塑(Alternating Tensor Reshaping)实现排列等变性:

Pi3核心代码(pi3/models/pi3.py:156-171)  
for i in range(len(self.decoder)):  
    blk = self.decoder[i]  
if i % 2 == 0:  
    # 偶数层:帧内独立处理  
    pos = pos.reshape(B*N, hw, -1)  # (B*N, hw, dim)  
    hidden = hidden.reshape(B*N, hw, -1)  
else:  
    # 奇数层:跨帧全局交互  
    pos = posreshape(B, N*hw, -1)  # (B, N*hw, dim)  
    hidden = hiddenreshape(B, N*hw, -1)  
hidden = blk(hidden, xpos=pos)  # 应用RoPE + Self-Attend

等变性保证

  1. 偶数层 (B∗N,hw,dim)(\mathbf{B}^{*}\mathbf{N},\mathbf{hw},\mathbf{dim})(BN,hw,dim)

每个视图独立处理
视图间无信息交互
排列不影响单视图结果

2.奇数层 (B,N∗hw,dim)(\mathbf{B},\mathbf{N}^{*}\mathbf{h}\mathbf{w},\mathbf{dim})(B,Nhw,dim)

。所有视图的所有token混合在一起
通过自注意力进行全局交互
。自注意力本身是排列等变的√

3.RoPE位置编码:

○ 相对位置编码,不依赖绝对顺序
○ 保持空间关系的等变性 ✓\checkmark

数学表达

fevenf_{\mathrm{even}}feven 为偶数层, foddf_{\mathrm{odd}}fodd 为奇数层:

偶数层:

fe v e n([x1,x2,…,xN])=[f(x1),f(x2),…,f(xN)] f _ {\text {e v e n}} ([ x _ {1}, x _ {2}, \dots , x _ {N} ]) = [ f (x _ {1}), f (x _ {2}), \dots , f (x _ {N}) ] fe v e n([x1,x2,,xN])=[f(x1),f(x2),,f(xN)]

奇数层:

fo d d(π([x1,…,xN]))=π(fo d d([x1,…,xN])) f _ {\text {o d d}} \left(\pi \left(\left[ x _ {1}, \dots , x _ {N} \right]\right)\right) = \pi \left(f _ {\text {o d d}} \left(\left[ x _ {1}, \dots , x _ {N} \right]\right)\right) fo d d(π([x1,,xN]))=π(fo d d([x1,,xN]))

整体网络:

f=fo d d∘fe v e n∘⋯∘fo d d∘fe v e n f = f _ {\text {o d d}} \circ f _ {\text {e v e n}} \circ \dots \circ f _ {\text {o d d}} \circ f _ {\text {e v e n}} f=fo d dfe v e nfo d dfe v e n

由于每层都是等变的,整个网络也是等变的。

关键技术差异

  1. 注意力机制
特性 VGGT Pi3
注意力类型 标准Self-Attention RoPE Self-Attention
位置编码 无显式位置编码 RoPE2D (旋转位置编码)
交替方式 帧内/全局交替 张量重塑交替
实现 两种不同的注意力层 同一种注意力层,不同输入形状

帧内自注意力

class FrameWiseAttention: def forward(self, tokens): # tokens: List[(K,C)] - 每帧独立 outputs = [] for frame_tokens in tokens: output = selfattention(frame_tokens) outputs.append(output) return outputs

全局自注意力

class GlobalAttention: def forward(self, tokens): #tokens:  $(N^{*}K,C)$  -所有帧混合 return selfattention(tokens)

Pi3的注意力实现

pi3/models/Layers/attention.py: FlashAttentionRope  
class FlashAttentionRope:  
    def forward(self, x, xpos):  
        # x: (B, N, C) - 可以是(B*N, hw, C)或(B, N*hw, C)  
        qkv = self.qkv(x)  
        q, k, v = split(qkv)  
    # 应用RoPE位置编码  
    q = self.lope(q, xpos) # 旋转位置编码  
    k = self.lope(k, xpos)  
    # Flash Attention  
    x = scaled.dot_product attention(q, k, v)  
    return x

关键区别:

  • VGGT: 通过不同的注意力层类型实现交替
  • Pi3: 通过改变输入张量形状实现交替,注意力层本身不变

2. 位置编码

VGGT: 无显式位置编码

VGGT依赖DINO预训练特征中隐含的位置信息,不添加额外的位置编码。

优点:

  • 简化架构
  • 依赖预训练知识

缺点:

  • 位置信息可能不够精确
    难以处理不同分辨率

Pi3: RoPE2D旋转位置编码

pi3/models/layers/post_embedding.py   
class RoPE2D: def__init__(self,freq  $\coloneqq$  100): selfFreq  $=$  freq   
defforward(self,q,xpos): #xpos:(B,N,2)-2D位置坐标 #计算旋转角度 theta  $=$  xpos\*selfFreq   
#应用旋转矩阵 cos_theta  $=$  torch.cos(theta) sin_theta  $=$  torch.sin(theta) #旋转q向量 q_rotated  $=$  rotate(q,cos_theta,sin_theta) return q_rotated

优点:

  • 相对位置编码,保持等变性
  • 精确的空间位置信息
  • 适应不同分辨率

缺点:

  • 增加计算复杂度
    需要额外的位置计算

3.坐标系统

特性 VGGT Pi3
预测坐标系 第一帧相机坐标系 局部相机坐标系
全局坐标 直接预测 通过变换矩阵计算
深度表示 直接预测深度图 预测局部3D点

VGGT的坐标系统

直接预测全局坐标

point_map = model/images) # (N, H, W, 3) - 在第一帧坐标系下

depth_map = model/images) # (N,H,W)(N, H, W)(N,H,W) - 深度值

camera.params === model/images) # (N,9)(N,9)(N,9) - [q,t,f]

特点:

  • 所有预测都在统一坐标系下
  • 第一帧相机固定为恒等变换
  • 点云直接可用,无需额外变换

Pi3的坐标系统

pi3/models/pi3.py: 192-209

  1. 预测局部坐标

local_points = model.point_head(hidden) # (B, N, H, W, 3)

  1. 预测相机位姿

camera_poses = model.camera_head(hidden) # (B, N, 4, 4)

  1. 变换到全局坐标

points = torch.einsum(‘bnij, bnhwj -> bnhwi’, camera�认点s, homogenize_points(local_points))[…,:3]

特点:

  • 两阶段预测:局部 →\rightarrow 全局
    每个视图有独立的局部坐标系
    通过相机位姿矩阵统一到全局

优势:

  • 更符合多视图几何原理
  • 局部预测更容易学习
  • 相机位姿可以独立优化

4. 训练策略

特性 VGGT Pi3
数据集数量 17+数据集 未明确说明
参数量 ~1.2B 较小(未明确)
训练时长 9天(64×A100) 未明确
损失函数 多任务联合 多任务联合
归一化 数据归一化 数据归一化

VGGT的损失函数

VGGT损失(论文Section3.4)L = L_camera + L_depth + L_pmap + 0.05 * L_track
相机损失 L_camera = Huber(pred_camera - gt_camera)

深度损失(带不确定性)

L_depth = |  $\Sigma_{-}D$  (D_pred - D gt) || + |  $\Sigma_{-}D$  (V_D_pred - V_Dgt)|| -  $\alpha$  log(ΣD)

点云损失(带不确定性)

L_pmap = || $\Sigma_P$ $\odot$  (P_pred - P_gt)|| + || $\Sigma_P$ $\odot$  ( $\nabla P_{pred} - \nabla P_{gt})||$  -  $\alpha$  log( $\Sigma_P$ )

追踪损失

L_track = ||y_pred - y_gt||

特点:

  • 使用Aleatoric不确定性加权
  • 包含梯度项 (边缘保持)
  • 追踪损失权重较小

Pi3的损失函数

Pi3损失(推测)  
L = L_local_points + L_conf + L_camera + L_global_points  
#局部点损失  
L_local_points = ||local_points_pred - local_points_gt||  
#置信度损失
L_conf = BCE(conf_pred, conf gt)

相机损失

L_camera = ||cameradetect - cameradetectgt||

全局点损失

L_global_points = ||points_pred - points_gt||

特点:

  • 同时监督局部和全局坐标
  • 显式的置信度预测
  • 相机位姿独立监督

代码实现对比

1. 编码器

VGGT

VGGT使用DINO特征提取

tokens = DINO/images) # (N, K, C)

添加特殊token

camera_tokens = [camera_token_1] + [camera_token_other] * (N-1)  
register_tokens = [register_token_1] + [register_token_other] * (N-1)
tokens = concat([tokens, camera_tokens, register_tokens])

Pi3

pi3/models/pi3.py:179-184

使用DINOv2编码器

imgs = imgs.reshape(B*N, _, H, W)  
hidden = selfencoder(imgs, is_training=True)
if isinstance(hidden, dict): hidden  $=$  hidden["x_normpatchtokens"]

对比:

  • 都使用DINO系列编码器
  • VGGT添加Camera Token,Pi3只添加Register Token
  • Pi3将所有图像展平为批次处理

2. 解码器主循环

VGGT (伪代码)

交替注意力

for layer_idx in range(24):
    if layer_idx % 2 == 0:
        # 帧内自注意力
        tokens = frame_wise attention(tokens)
    else:
        # 全局自注意力
        tokens = globalattention(tokens)

Pi3

pi3/models/pi3.py:156-171   
for i in range(len(selfdecoder)): blk  $=$  selfdecoder[i] if  $\texttt{i}\% 2 = = 0$  #偶数层:帧内独立 pos  $=$  pos.reshape(B*N,hw,-1) hidden  $=$  hidden.reshape(B*N,hw,-1) else:#奇数层:跨帧交互 pos  $=$  pos.reshape(B,N\*hw,-1) hidden  $=$  hiddenreshape(B,N\*hw,-1) hidden  $=$  blk(hidden,xpos=pos)
保存最后两层输出 if i+1 in [len(self.decoder)-1, len(self.decoder)]: final_output.append(hidden.reshape(B*N, hw, -1)) return torch.cat([final_output[0], final_output[1]], dim=-1)

关键差异:

  1. VGGT: 使用不同类型的注意力层
  2. Pi3: 使用相同的注意力层,通过reshape改变交互模式
  3. Pi3: 拼接最后两层输出作为最终特征

3. 预测头

相机头

camera.params = camera_head(camera_tokens) # (N, 9)

DPT密集预测头

Pi3

features = DPT(image_tokens) # (N, C, H, W)  
depth = conv3x3(features) # (N, 1, H, W)  
point_map = conv3x3(features) # (N, 3, H, W)  
track_features = conv3x3(features) # (N, C, H, W)
CoTracker2追踪头  
tracks = CoTracker2(train_features, querypoints)
pi3/models/pi3.py: 188-209

点云解码器

point Hidden  $=$  self point decoder (hidden, xpos=pos)   
ret  $=$  self point head([point hidden[:, self.patch_startidx:]], (H, W))   
xy, z  $=$  ret.split([2, 1], dim=-1)   
z  $=$  torch.exp(z)   
local points  $=$  torch.cat([xy \* z, z], dim=-1)

置信度解码器

conf-hidden = self.conf Decoder(hidden, xpos=pos)  
conf = self.conf_head([conf-hidden[:, self.patch_startidx:]], (H, W))

相机解码器

camera_hidlen  $=$  self.camera Decoder(hiden, xpos  $\equiv$  pos)   
camera_poses  $=$  self.camera_head-camera_hiden[:,self.patch_startidx:], patch_h,patch_w)

全局坐标变换

points = torch.einsum('bnij, bnhwj -> bnhwi', camera�认点s, homogenize_points(local_points))[...:3]

关键差异:

  1. VGGT: 直接预测全局点云和深度
  2. Pi3: 预测局部点云,通过相机位姿变换到全局
  3. Pi3: 使用独立的Transformer解码器,而非简单的卷积层
  4. Pi3: 显式预测置信度

Pi3排列等变性的深入解释

为什么交替重塑能保证等变性?

数学证明

设输入为 X=[x1,x2,…,xN]X = [x_{1}, x_{2}, \ldots, x_{N}]X=[x1,x2,,xN] ,排列为 π\piπ

偶数层(形状:B*N, hw, dim):

输入:[x_1, x_2, …, x_N]

处理:[f(x_1),f(x_2),…,f(x_N)]

排列后: π([f(x−1),f(x−2),…,f(x−N)])\pi ([f(x_{-}1),f(x_{-}2),\dots ,f(x_{-}N)])π([f(x1),f(x2),,f(xN)])

由于每个视图独立处理,排列不影响单个视图的输出。

奇数层(形状:B,N*hw,dim):

输入:concat([x_1, x_2, …, x_N]) # 形状:(B, N*hw, dim)

自注意力:Attention(Q, K, V)

自注意力的等变性:

Attention⁡(π(X))=π(Attention⁡(X)) \operatorname {A t t e n t i o n} (\pi (X)) = \pi (\operatorname {A t t e n t i o n} (X)) Attention(π(X))=π(Attention(X))

这是因为:

  1. 注意力权重矩阵 A=softmax⁡(QKT)A = \operatorname{softmax}(QK^T)A=softmax(QKT) 对输入排列是对称的
  2. 加权求和 AVAVAV 保持排列等变性

组合等变性:

ft o t a l=fo d d∘fe v e n∘⋯∘fo d d∘fe v e n f _ {\text {t o t a l}} = f _ {\text {o d d}} \circ f _ {\text {e v e n}} \circ \dots \circ f _ {\text {o d d}} \circ f _ {\text {e v e n}} ft o t a l=fo d dfe v e nfo d dfe v e n

由于每层都是等变的,整个网络也是等变的。

可视化理解

输入:[A, B, C] (3张图片)

偶数层 (B∗N,hw,dim)(\mathsf{B}^{*}\mathsf{N},\mathsf{hw},\mathsf{dim})(BN,hw,dim)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

奇数层 (B, N*hw, dim):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果输入改为 [B,A,C][B, A, C][B,A,C] :

偶数层:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

奇数层:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结论:输入顺序改变 →\rightarrow 输出顺序相应改变 →\rightarrow 等变性√

RoPE的作用

RoPE (Rotary Position Embedding) 在等变性中的作用:

传统位置编码(破坏等变性)

pos_embedding = [0, 1, 2, 3, …] # 绝对位置

x=x+pos_embed[i]\mathbf{x} = \mathbf{x} + \mathbf{pos\_embed}[i]x=x+pos_embed[i] #依赖绝对位置

RoPE(保持等变性)  
q = rotate(q, position) #相对位置旋转  
k = rotate(k, position)  
attention = softmax(q @ k^T) @ v #只依赖相对位置

为什么RoPE保持等变性?

  1. 相对位置: RoPE编码的是token之间的相对位置, 而非绝对位置
  2. 旋转不变性: 旋转操作对所有token一致应用
  3. 注意力对称性: 相对位置关系在排列后保持不变

示例:

原始:[A,B,C]

相对位置:A-B=1,B-C=1,A-C=2

排列后:[B,A,C]

相对位置:B-A=-1,A-C=1,B-C=2

RoPE编码的是相对位置差,排列后相对关系保持不变

为什么VGGT没有Pi3的核心优势?

1. 第一帧依赖问题 (Frame-1 Dependency)

VGGT的设计缺陷

VGGT将第一帧作为特殊的参考帧,这带来了几个根本性问题:

# VGGT的第一帧特殊化  
camera_token_1 = learnable_token_1 # 第一帧专用  
camera_token_other = learnable_token_2 # 其他帧共享

第一帧相机固定为恒等变换

q1 = [0, 0, 0, 1] # 恒等旋转  
t1 = [0, 0, 0] # 零平移
所有预测都在第一帧坐标系下point_map_i = predict_in_frame1_coordinates(image_i)

问题分析:

1. 破坏完全等变性:

输入:[A,B,C]

输出:points_in_A_coordinates

输入:[B,A,C] # 改变顺序

输出:points_in_B_coordinates #坐标系改变!

虽然VGGT声称对第2~N帧是等变的,但由于第一帧的特殊性,整体输出并非真正等变。

2. 第一帧质量依赖

如果第一帧模糊、遮挡或光照不佳,整个重建质量下降
第一帧的选择成为关键超参数
○ 无法自动选择最佳参考帧

3.坐标系不稳定:

场景1:第一帧是正面视角

points_1 = VGGT([front, left, right]) # 坐标系:正面

场景2:第一帧是侧面视角

points_2 = VGGT([left, front, right]) # 坐标系:侧面

points_1 和 points_2 在不同坐标系下,需要额外对齐

Pi3的解决方案

Pi3通过局部坐标系 + 相机位姿变换避免了这个问题:

Pi3:所有帧平等对待

for i in range(N): local_points_i = predict_local(image_i) #各自的局部坐标系 camera_pos_i = predict-camera(image_i) #相对位姿

统一到全局坐标系

global_points = camera�认作 @ local_points

优势:

  • ✓\checkmark 所有帧平等,无特殊帧
  • 输入顺序改变,输出坐标系不变
  • 可以自动选择最佳全局坐标系
  1. 位置编码缺失问题 (Missing Position Encoding)

VGGT不使用显式位置编码,依赖DINO预训练特征中的隐含位置信息:

# VGGT
tokens = DINO/images) # 依赖预训练的位置信息
# 没有额外的位置编码
output = transformer(tokens)

问题分析:

1. 位置信息不精确:

DINO的位置信息是为分类任务设计的,不是为3D重建优化的
缺乏精确的像素级空间关系

2. 分辨率泛化差:

训练:518×518  
model.train/images_518)
测试:1024×1024  
model.test/images_1024) #位置信息可能失效

没有显式位置编码,模型难以泛化到不同分辨率。

3. 相对位置关系模糊

。无法明确编码token之间的相对位置
○ 多视图几何依赖精确的空间关系

Pi3的RoPE位置编码

Pi3使用RoPE2D提供精确的相对位置信息:

Pi3   
class RoPE2D: defforward(self,q,xpos): #xpos:(B,N,2-精确的2D坐标 theta=xpos\*selfFreq#频率编码 #旋转编码 cos_theta  $\equiv$  torch.cos(theta) sin_theta  $=$  torch.sin(theta) q_rotated  $\equiv$  rotate(q,cos_theta,sin_theta) returnq_rotated

优势:

1. 精确的相对位置:

Token A at (10, 20)

Token B at (15, 25)

RoPE编码:相对距离 =sqrt((15−10)2+(25−20)2)=7.07= \text{sqrt}((15 - 10)^2 + (25 - 20)^2) = 7.07=sqrt((1510)2+(2520)2)=7.07

注意力权重 ∝exp⁡(−distance)\propto \exp (-\text{distance})exp(distance)

2.分辨率无关:

○ RoPE基于相对位置,自动适应不同分辨率
训练和测试分辨率可以不同

3. 保持等变性:

○ 相对位置编码不依赖绝对顺序
排列后相对关系保持不变

3. 几何一致性问题 (Geometric Consistency)

VGGT的直接预测

VGGT直接预测全局点云,缺乏几何约束:

VGGT

point_map = DPT_head(features) # 直接预测3D点

depth_map = DPT_head(features) # 独立预测深度

问题:point_map 和 depth_map 可能不一致

没有强制的几何约束

问题分析:

1. 元余预测不一致:

理论上应该满足

point_map = unproject(depth_map, camera_parameters)

但VGGT的预测可能不满足

point_map_pred ≠\neq= unproject(depth_pred, camera_pred)

虽然论文提到“在推理时组合深度和相机参数更准确”,但这暴露了预测不一致的问题。

2. 缺乏多视图约束

每个视图的点云独立预测

○ 没有显式的多视图几何约束
○ 依赖网络隐式学习一致性

3.难以融合多视图:

VGGT需要后处理融合

points_1 = predict_view_1 # 在frame1坐标系

points_2 = predict_view_2 # 在frame1坐标系

如何融合?需要额外的对齐和融合算法

merged = align_and_merge(points_1, points_2)

Pi3的几何一致性设计

Pi3通过局部预测 + 相机变换保证几何一致性:

Pi3

  1. 预测局部坐标(相机坐标系)

local_points = predict_local(image) # (x,y,z)(x,y,z)(x,y,z) in camera coords

2. 预测相机位姿

camera_pos = predict_camera(image) # 4×44 \times 44×4 变换矩阵

  1. 几何变换到全局

global_points = cameraPose @ homogenize(local_points)

保证:几何关系严格满足

优势:

1. 强制几何约束:

#局部点 →\rightarrow 全局点的变换是精确的

P_global = R @ P_local + t

不存在不一致的问题

2. 多视图自然融合

所有视图的点都在统一的全局坐标系

points_1 = camera_1 @ local_1

points_2 = camera_2 @ local_2

自动对齐,无需额外处理  
merged = concat([points_1, points_2])

3. 符合多视图几何原理

○ 局部预测 →\rightarrow 相机坐标系 (单视图几何)
○ 相机位姿 →\rightarrow 外参矩阵 (多视图几何)
○ 全局变换 →\rightarrow 世界坐标系 (场景重建)

4. 交替注意力的局限性 (Alternating-Attention Limitations)

VGGT的交替注意力

VGGT伪代码  
for layer_idx in range(24):  
    if layer_idx % 2 == 0:  
        # 帧内自注意力  
    for i in range(N):  
        tokens[i] = frame_wise attention(tokens[i])  
else:  
    # 全局自注意力  
    all_tokens = concat(tokens)  
    all_tokens = globalattention(all_tokens)

问题分析:

1. 两种注意力层的不对称

帧内层和全局层是不同的网络模块
参数不共享,增加模型复杂度
难以保证两种层的行为一致性

2. 帧内层的信息瓶颈

帧内层:每帧独立  
tokens[0] = attention(tokens[0]) #只看到view 0  
tokens[1] = attention(tokens[1]) #只看到view 1  
#信息无法跨视图流动  
#依赖下一个全局层才能交互

3. 全局层的计算复杂度

全局层:所有token混合all_tokens  $=$  concat([tokens[0],...,tokens[N-1]])

形状: (N∗K,C)(N^{*}K,C)(NK,C) -如果 N=100N = 100N=100K=1024K = 1024K=1024 ,则100K个token

自注意力复杂度: O((N∗K)∧2)O((N^{*}K)^{\wedge 2})O((NK)2)

NNN 很大时, 计算量爆炸

Pi3的交替重塑

Pi3

for i in range(len(selfdecoder)):

if i % 2 == 0:

偶数层:帧内独立

hidden = hidden.reshape(B*N, hw, -1)

else:

奇数层:跨帧交互

hidden = hidden.reshape(B, N*hw, -1)

hidden = same attentio block(hiden, xpos=pos)

优势:

1. 统一的注意力层:

○ 所有层使用相同的BlockRope
参数共享,模型更简洁
• 行为一致性有保证

2. 灵活的信息流动:

偶数层: (B∗N,hw,−1)(B^{*}N,hw, - 1)(BN,hw,1)
每个视图内部充分交互
奇数层:(B, N*hw, -1)
所有视图的所有token混合
信息流动更自由

3.计算效率:

通过reshape控制注意力范围
。可以根据需要调整交替频率
○ 更容易优化和并行化

5. 训练数据依赖问题 (Data Dependency)

VGGT的大规模数据依赖

VGGT依赖大规模数据训练:

  • 17+ 数据集
  • 1.2B 参数
  • 64xA100 GPU
  • 9天训练时间

问题分析:

1. 高昂的训练成本:

需要大量计算资源
难以复现和微调
不适合资源受限的场景

2. 数据偏差风险:

如果训练数据主要是室内场景

model.train(indoorDatasets)

在室外场景可能表现不佳

model.test(outdoorscene) #泛化能力受限

3. 隐式学习的不可控性

○ 依赖网络从数据中隐式学习几何关系
缺乏显式的几何约束
难以诊断和修复错误

Pi3的几何先验设计

Pi3通过显式的几何设计减少数据依赖:

Pi3的几何先验

  1. 局部坐标系(单视图几何)

local_points = predict_local(image)

2. 相机位姿(多视图几何)

camera_pos = predict_camera(image)

3. 几何变换 (刚体变换)

global_points = cameraPOSE @ local_points

优势:

1. 更少的数据需求:

。几何约束减少了需要学习的自由度
。 可以在较小数据集上训练

2. 更好的泛化能力:

○ 几何原理是通用的
。不依赖特定场景的数据分布

3. 可解释性和可控性

○ 每个组件有明确的几何意义
○ 容易诊断和改进

6. 等变性的理论保证 (Theoretical Guarantee)

VGGT的隐式等变性

VGGT依赖自注意力的隐式等变性:

VGGT

全局自注意力是等变的(理论上)

output = selfattention(input)

但是:

  1. 第一帧特殊化破坏了完全等变性

2. 没有显式的等变性验证

#3.依赖网络学习等变行为

问题:

  • X 第一帧不参与排列 →\rightarrow 不是完全等变
  • X 没有理论保证 →\rightarrow 依赖经验验证
  • ✘难以证明→黑盒行为

Pi3的显式等变性

Pi3通过设计保证等变性:

Pi3的等变性证明

偶数层:独立处理

f_even([x1, x2, ..., xN]) = [f(x1), f(x2), ..., f(xN)]

排列等变:√

奇数层:自注意力

$\mathsf{f\_odd}(\pi (\mathsf{X})) = \pi (\mathsf{f\_odd}(\mathsf{X}))$

自注意力等变:√

组合: f=f_odd∘f_even∘⋯∘f_odd∘f_evenf = f\_ odd\circ f\_ even\circ \dots \circ f\_ odd\circ f\_ evenf=f_oddf_evenf_oddf_even

等变函数的组合仍然等变:

优势:

数学上可证明的等变性

  • 所有帧平等对待
    不依赖网络学习等变行为

7. 实际应用的灵活性 (Practical Flexibility)

VGGT的限制

1. 第一帧选择问题:

用户必须决定哪一帧作为参考

results = VGGT([frame_0, frame_1, …, frame_N])

frame_0 的质量影响整体结果

2. 增量重建困难

场景1:重建前3帧

result_1 = VGGT([A, B, C]) # A是参考帧

场景2:添加第4帧

result_2 = VGGT([A, B, C, D]) # 需要重新计算所有

无法增量更新

3. 多序列融合复杂

#序列1

points_1 = VGGT([A, B, C]) # 在A坐标系

#序列2

points_2 = VGGT([D, E, F]) # 在D坐标系

融合需要额外对齐

merged = align(points_1, points_2)

Pi3的灵活性

1. 无需选择参考帧

任意顺序都可以

r e s u l t1=P i 3([A,B,C]) \text {r e s u l t} _ {1} = \text {P i 3} ([ A, B, C ]) r e s u l t1=P i 3([A,B,C])

r e s u l t2=Pi3⁡([B,A,C]) \text {r e s u l t} _ {2} = \operatorname {P i 3} ([ B, A, C ]) r e s u l t2=Pi3([B,A,C])

r e s u l t3=Pi3⁡([C,B,A]) \text {r e s u l t} _ {3} = \operatorname {P i 3} ([ C, B, A ]) r e s u l t3=Pi3([C,B,A])

结果在同一全局坐标系

2. 支持增量重建

初始重建

r e s u l t1=P i 3([A,B,C]) \text {r e s u l t} _ {1} = \text {P i 3} ([ A, B, C ]) r e s u l t1=P i 3([A,B,C])

添加新帧(可以只计算新帧)

l o c a lD=p r e d i c tlocal(D) \text {l o c a l} _ {\mathrm {D}} = \text {p r e d i c t} _ {\mathrm {l o c a l}} (\mathrm {D}) l o c a lD=p r e d i c tlocal(D)

cameraD=predictcamera(D) c a m e r a _ {D} = p r e d i c t _ {c a m e r a} (D) cameraD=predictcamera(D)

points_D=camera_D@local_D p o i n t s \_ D = c a m e r a \_ D @ l o c a l \_ D points_D=camera_D@local_D

增量更新

r e s u l t2=m e r g e(r e s u l t1,p o i n t sD) \text {r e s u l t} _ {2} = \text {m e r g e} (\text {r e s u l t} _ {1}, \text {p o i n t s} _ {D}) r e s u l t2=m e r g e(r e s u l t1,p o i n t sD)

3. 自然的多序列融合:

所有序列在统一坐标系

p o i n t s−1=Pi3⁡([A,B,C]) \text {p o i n t s} _ {- 1} = \operatorname {P i 3} ([ A, B, C ]) p o i n t s1=Pi3([A,B,C])

points2=Pi3⁡([D,E,F]) p o i n t s _ {2} = \operatorname {P i 3} ([ D, E, F ]) points2=Pi3([D,E,F])

直接融合,无需对齐

m e r g e d=c o n c a t([p o i n t s1,p o i n t s2]) \text {m e r g e d} = \text {c o n c a t} ([ \text {p o i n t s} _ {1}, \text {p o i n t s} _ {2} ]) m e r g e d=c o n c a t([p o i n t s1,p o i n t s2])

总结对比表

维度 VGGT Pi3 Pi3优势
第一帧依赖 第一帧特殊化 所有帧平等 无特殊帧,更稳定
位置编码 无显式编码 RoPE2D 精确相对位置
几何一致性 直接预测 局部+变换 强制几何约束
交替机制 两种注意力层 统一注意力+reshape 更简洁高效
数据依赖 1.2B参数,17+数据集 较小模型 更少资源需求
等变性保证 隐式(除第一帧) 显式(所有帧) 理论保证
应用灵活性 受限于第一帧 完全灵活 增量重建,多序列融合

核心洞察:为什么Pi3的设计更优?

1. 哲学层面

VGGT: “用足够大的模型和足够多的数据,让网络自己学习”

  • 优点: 简单, 依赖规模
  • 缺点: 成本高, 不可控, 缺乏理论保证

Pi3:“显式设计几何约束,让网络学习更容易”

  • 优点: 高效, 可控, 有理论保证
  • 缺点: 需要更多设计思考

2. 工程层面

VGGT的工程挑战:

  1. 第一帧选择

best_frame = select_best_reference(frame) # 需要额外逻辑

2. 坐标系对齐

if reference_changed: points = transform_to_new_reference(points) #额外计算

  1. 多序列融合

merged = complex Alignment_and_fusion(seq1, seq2) # 复杂后处理

Pi3的工程简洁性

  1. 无需选择参考帧

results = Pi3(frame) # 任意顺序

2. 统一坐标系

所有输出自动对齐

  1. 简单融合

merged = concat([results1, results2]) # 直接拼接

3. 科学层面

VGGT: 经验驱动 (Empirical)

  • 依赖大规模实验验证
    缺乏理论分析

  • 黑盒行为

  • 基于多视图几何理论

  • 可证明的等变性

  • 可解释的行为

总结

VGGT的优势

  1. 大规模训练: 1.2B参数, 17+17+17+ 数据集, 强大的泛化能力
  2. 多任务学习:同时预测相机、深度、点云、追踪
  3. 端到端: 无需后处理即可获得高质量结果
  4. 简洁架构: 最小3D归纳偏置,依赖数据驱动

Pi3的优势

  1. 显式等变性: 通过交替重塑明确保证排列等变性
  2. 精确位置编码: RoPE提供精确的相对位置信息
  3. 几何一致性:局部到全局的两阶段预测更符合几何原理
  4. 轻量高效: 相对更小的模型, 更快的推理速度

排列等变性实现对比

方面 VGGT Pi3
实现方式 交替注意力 交替张量重塑
等变性保证 隐式(自注意力对称性) 显式(reshape + 自注意力)
位置编码 RoPE (相对位置)
第一帧处理 特殊化(不参与排列) 与其他帧相同
坐标系 第一帧坐标系 局部坐标系+变换

核心洞察

Pi3通过什么实现排列等变性?

1. 交替张量重塑:

○ 偶数层: 视图独立处理 →\rightarrow 排列不影响单视图
奇数层: 全局混合处理 →\rightarrow 自注意力保证等变性

2.RoPE位置编码:

○ 相对位置编码,不依赖绝对顺序
○ 保持空间关系的等变性

3. 对称的自注意力:

• 注意力权重计算对输入顺序对称
。加权求和保持排列等变性

4. 局部到全局变换

○ 局部坐标预测与视图顺序无关
○ 全局变换通过相机位姿统一

与VGGT的本质区别:

  • VGGT: 依赖自注意力的隐式等变性 + 第一帧锚定
  • Pi3: 显式设计的等变架构 + 相对位置编码

两者都实现了排列等变性,但Pi3的实现更加显式和可解释。

实际应用场景对比

场景1: 无人机航拍重建

任务: 从无人机拍摄的100张照片重建地形

VGGT的挑战

问题1:第一帧选择
无人机起飞时可能有遮挡或模糊

frames = load(drone_images() # 100张

first_frame = frames[0] # 可能质量不佳

问题2:计算复杂度

100帧 ×1024\times 1024×1024 tokens =102,400= 102,400=102,400 tokens

全局注意力: 0(102,400∧2)≈10B0(102,400^{\wedge}2)\approx 10B0(102,4002)10B operations

问题3:内存限制

可能需要分批处理,然后融合

batch1 = VGGT(frame[0:32]) # 在frame[0]坐标系

batch2 = VGGT(frame[32:64]) # 在frame[32]坐标系

batch3 = VGGT(frame[64:100]) # 在frame[64]坐标系

需要复杂的对齐和融合

Pi3的优势

优势1:无需担心第一帧质量

frames = load(drone_images())

results = Pi3(frame) # 任意顺序都可以

优势2:支持增量处理

initial  $=$  Pi3(frame[0:50])   
for i in range(50, 100): new_points  $=$  Pi3(process_single(frame[i]) initial  $=$  merge(initial, new_points)

优势3:统一坐标系

所有点自动在全局坐标系下,无需对齐

场景2: 实时SLAM (同步定位与建图)

任务:机器人实时建图导航

VGGT的限制

问题:第一帧固定

机器人启动时的第一帧成为永久参考

first_frame = capture() # t=0
reference_frame = first_frame # 固定

随着机器人移动,第一帧可能不再可见

for t in range(1, 1000):
    new_frame = capture()
    # 所有预测仍在first_frame坐标系
    # 但first_frame已经不在视野中
    points = VGGT([first_frame, ..., new_frame])

累积误差增大

Pi3的优势

优势:灵活的参考帧

for t in range(1000):
    new_frame = capture()
# 可以动态选择最佳参考帧
if t % 10 == 0:
    # 每10帧重新选择参考
    reference = select_best_frame(recent Frames)
# 局部坐标系 + 相机位姿
# 自动处理坐标系变换
points = Pi3(recent Frames)

场景3: 多相机系统

任务:多个相机同时拍摄,融合重建

VGGT的复杂性

相机1:拍摄序列A

seq⁡A=[A1,A2,A3,A4,A5] \operatorname {s e q} _ {\mathrm {A}} = [ \mathrm {A} 1, \mathrm {A} 2, \mathrm {A} 3, \mathrm {A} 4, \mathrm {A} 5 ] seqA=[A1,A2,A3,A4,A5]

points_A = VGGT(seq_A) # 在A1坐标系

相机2:拍摄序列B

seq⁡B=[B1,B2,B3,B4,B5] \operatorname {s e q} _ {\mathrm {B}} = [ \mathrm {B} 1, \mathrm {B} 2, \mathrm {B} 3, \mathrm {B} 4, \mathrm {B} 5 ] seqB=[B1,B2,B3,B4,B5]

points_B = VGGT(seq_B) # 在B1坐标系

相机3:拍摄序列C

seq⁡C=[C1,C2,C3,C4,C5] \operatorname {s e q} _ {\mathrm {C}} = [ \mathrm {C} 1, \mathrm {C} 2, \mathrm {C} 3, \mathrm {C} 4, \mathrm {C} 5 ] seqC=[C1,C2,C3,C4,C5]

points_C = VGGT(seq_C) # 在C1坐标系

问题:三个不同的坐标系

需要复杂的多视图对齐

transform_AB = estimate_transform(points_A, points_B)

transform_AC = estimate_transform(points_A, points_C)

points_B_aligned = transform_AB @ points_B

points_C_aligned = transform_AC @ points_C

merged = merge([points_A, points_B_aligned, points_C_aligned])

Pi3的简洁性

所有序列在统一坐标系

seq⁡A=[A1,A2,A3,A4,A5] \operatorname {s e q} _ {\mathrm {A}} = [ \mathrm {A} 1, \mathrm {A} 2, \mathrm {A} 3, \mathrm {A} 4, \mathrm {A} 5 ] seqA=[A1,A2,A3,A4,A5]

seq⁡B=[B1,B2,B3,B4,B5] \operatorname {s e q} _ {\mathrm {B}} = [ \mathrm {B} 1, \mathrm {B} 2, \mathrm {B} 3, \mathrm {B} 4, \mathrm {B} 5 ] seqB=[B1,B2,B3,B4,B5]

seq⁡C=[C1,C2,C3,C4,C5] \operatorname {s e q} _ {\mathrm {C}} = [ \mathrm {C} 1, \mathrm {C} 2, \mathrm {C} 3, \mathrm {C} 4, \mathrm {C} 5 ] seqC=[C1,C2,C3,C4,C5]

points_A=Pi3(s e q−A) p o i n t s \_ A = P i 3 (\text {s e q} _ {-} A) points_A=Pi3(s e qA)

pointsB=P i 3 (s e qB) p o i n t s _ {B} = \text {P i 3 (s e q} _ {B}) pointsB=P i 3 (s e qB)

points_C=Pi3(s e q_C) p o i n t s \_ C = P i 3 (\text {s e q} _ {\_} C) points_C=Pi3(s e q_C)

直接融合,无需对齐

m e r g e d=c o n c a t([p o i n t sA,p o i n t sB,p o i n t sC]) \text {m e r g e d} = \text {c o n c a t} ([ \text {p o i n t s} _ {\mathrm {A}}, \text {p o i n t s} _ {\mathrm {B}}, \text {p o i n t s} _ {\mathrm {C}} ]) m e r g e d=c o n c a t([p o i n t sA,p o i n t sB,p o i n t sC])

场景4: 视频重建

任务: 从视频中重建动态场景

视频:30fps,10秒  $= 300$  帧 video_frames  $=$  load_video() #300
问题1:无法一次处理所有帧  
# VGGT最多处理几十帧
问题2:滑动窗口处理  
window_size = 32  
results = []  
for i in range(0, 300, window_size):  
    window = video Frames[i:i+window_size]  
    result = VGGT(window) # 在window[0]坐标系  
results.append(result)
# 问题3:窗口间对齐  
# 每个窗口有不同的参考帧  
aligned_results = []  
for i in range(len(results)-1):  
    transform = estimate_transform(results[i], results[i+1])  
    aligned_results.append(transform @ results[i+1])

Pi3的流式处理

支持流式处理  
video_frames = load Video() # 300帧
方案1:滑动窗口 + 自动对齐  
window_size = 16  
overlap = 6  
results = []  
for i in range(0, 300, window_size - overlap):  
    window = video Frames[i:i+window_size]  
    result = Pi3(window)  
    results.append(result)
自动在统一坐标系,无需对齐 merged = concat(results)
方案2:增量处理  
state = Pi3.init()  
for frame in video Frames: state = Pi3.update(state, frame)
实时获取重建结果 current_points = state.get_points()

场景5: 稀疏视图重建

任务:从3-5张照片重建物体

VGGT的过度设计

只有3张图片 images = [img1, img2, img3]
VGGT: 1.2B参数模型  
# 对于3张图片来说过于庞大  
result = VGGT/images) # 大材小用
问题:  
# - 计算资源浪费  
# - 推理速度慢  
# - 第一帧依赖仍然存在

Pi3的高效性

3张图片 images = [img1, img2, img3]
Pi3: 更轻量的模型  
result = Pi3/images) # 快速推理
# 优势:  
# - 更快的速度  
# - 更少的内存  
# - 仍然保持高质量

性能对比总结

场景 VGGT挑战 Pi3优势
大规模重建 第一帧选择,分批对齐 增量处理,统一坐标系
实时SLAM 第一帧固定,累积误差 动态参考,灵活变换
多相机系统 多坐标系对齐 自动统一坐标系
视频重建 滑动窗口对齐 流式处理,自动对齐
稀疏视图 模型过大 轻量高效

最终结论

VGGT适合的场景

  1. 离线批处理:有充足时间和资源
  2. 固定视角: 第一帧质量有保证
  3. 单序列重建: 不需要多序列融合
  4. 追求极致精度: 愿意投入大量计算资源

Pi3适合的场景

  1. 实时应用: SLAM, AR/VR
  2. 增量重建: 逐步添加新视图
  3. 多序列融合: 多相机系统
  4. 资源受限: 移动设备, 边缘计算
  5. 需要理论保证: 关键应用

核心差异总结

VGGT的哲学:“Scale is all you need”

  • 用规模解决问题
  • 依赖大数据和大模型
    隐式学习几何关系

Pi3的哲学:“Geometry is all you need”

  • 用几何约束解决问题
  • 显式设计等变性
  • 理论驱动的架构

最终判断:

  • 如果你有无限的计算资源和数据 →\rightarrow VGGT
  • 如果你需要高效、可控、可解释的方案 →\rightarrow Pi3

参考资料

  1. VGGT论文: “VGGT: Visual Geometry Grounded Transformer” (2025)

o arXiv: https://arxiv.org/html/2503.11651v1
GitHub: https://github.com/facebookresearch/vggt

2. Pi3代码:

。 pi3/models/pi3.py: 主模型实现
o pi3/models/layers/attention.py: RoPE注意力
o pi3/models/layers/block.py: BlockRope实现

3. 相关工作:

DUSt3R: 点云预测的先驱工作

  • MAST3R: DUS3R的改进版本
    ○ VGGSfM: 可微分SfM

文档创建时间:2025 作者:AI Assistant 用途:对比分析VGGT与Pi3的架构差异,深入解释Pi3的排列等变性实现机制

快速参考卡片

VGGT vs Pi3 一句话总结

模型

核心理念

一句话总结

VGGT

Scale is all you need

用1.2B参数和17+数据集,让网络隐式学习3D几何

Pi3

Geometry is all you need

用显式几何约束和等变设计,让网络高效学习3D重建

关键差异速查表

VGGT vs Pi3 核心差异

第一帧依赖:

VGGT:

第一帧特殊化,破坏完全等变性

Pi3:

所有帧平等,完全等变

位置编码:

VGGT:

无显式编码,依赖DINO隐含信息

Pi3:

RoPE2D精确相对位置编码

几何一致性:

VGGT:

直接预测,可能不一致

Pi3:

局部+变换,强制几何约束

交替机制:

VGGT:

两种不同注意力层

Pi3:

统一注意力+reshape

资源需求:

VGGT: 1.2 B1.2 \mathrm{~B}1.2 B 参数, 64×A10064 \times \mathrm{A} 10064×A100 , 9天

Pi3: 更小模型,更少资源

理论保证:

VGGT: × 隐式等变性, 无理论证明

Pi3: 显式等变性, 可数学证明

应用灵活性:

VGGT: ×\times× 受限于第一帧, 难以增量更新

Pi3: ✓\checkmark 完全灵活,支持增量和多序列

选择指南

选择VGGT,如果你:

  • 有充足的计算资源 (多GPU集群)
  • 需要处理极端复杂场景
  • 可以接受第一帧依赖
  • ✓\checkmark 追求极致精度,不在乎成本

选择Pi3,如果你:

  • 需要实时或近实时处理
    资源受限 (单GPU或移动设备)
  • 需要增量重建或多序列融合
    需要理论保证和可解释性
  • ✓\checkmark 追求效率和灵活性
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐