
做视觉定位和三维重建的朋友这两年应该没少被VGGT刷屏。它把多视角图像的相机位姿估计、内参预测和3D点生成全部塞进一个端到端Transformer一个前向网络跑完场景结构直接出来省掉了特征匹配、RANSAC、全局优化这一整套传统SfM流程。精度确实能打但问题也同样明显模型体量大、推理慢、显存吃紧想在实时的SLAM前端或者大规模图像集粗定位里用它压力很大。最近开源社区放出了一个叫LiteVGGT的轻量版本官方说法很直接——比VGGT快10倍左右定位精度和重建质量基本无损。这听起来像是“既要马儿跑又要马儿不吃草”的广告词但我把它拉下来在自己手头的数据集上完整跑了一遍又翻了源码和release说明发现这个加速不是靠简单砍层数砍参数量硬凑出来的而是把注意力机制、token密度、蒸馏策略、推理精度这几个维度一起做了调整。这篇文章就把我拆解到的原理、实测流程和踩过的坑一次说清楚给想把它接进自己项目的朋友做一个参考。1. 先搞清楚VGGT在解决什么问题LiteVGGT又在改什么VGGT这类前馈式三维感知模型本质上是把传统的“几何优化”问题变成了“序列预测”问题。传统SfM的处理链路很长先提特征、做特征匹配、跑RANSAC估计基础矩阵或本质矩阵最后用Bundle Adjustment反复优化相机参数和3D点。这套流程在纹理丰富的场景下效果很好但遇到弱纹理、重复结构、大视角变化匹配噪声一上来迭代就非常容易崩。VGGT的思路完全不同。它输入一批无序图像在Transformer内部通过注意力机制隐式建立跨视图对应关系然后把相机外参、内参、逐像素3D点图当作输出头直接回归出来。整个过程不需要显式匹配不需要RANSAC也不需要BA。对下游任务来说它最大的价值是提供了一个温和、稳定、可微分的“几何初始化器”NeRF和3DGS训练之前不再必须依赖COLMAP跑几十分钟。但代价也藏在架构里。VGGT的骨干网络规模不小而且用的是标准全局注意力。输入9张1024分辨率的图切patch之后token数量直接到几万级别注意力矩阵的尺寸是token数平方显存和时间都吃得很凶。我实际测下来的体验是模型装得上去但跑一次推理要等batch稍大一点GPU就开始报警。LiteVGGT做的事情不是把VGGT砍成一个小号版本这么简单。它保留了VGGT的输入输出接口和核心输出头也就是说你原来写的下游解析代码基本不用改模型名一换就能接进去。但内部骨干网络、注意力计算方式、token处理逻辑都重做了。官方把它定义为“保持精度的轻量化版本”而不是“牺牲精度的快速版”这个词是有讲究的后面讲蒸馏的时候再展开。如果用一张表来对比传统SfM、VGGT和LiteVGGT的定位大概是这样的方案核心流程速度特征精度特征部署友好度传统SfM特征匹配RANSACBA慢分钟到小时级成熟场景下很稳依赖COLMAP等外部工具VGGT端到端Transformer前向中等显存占用高泛化强开箱即用大模型部署成本高LiteVGGT轻量Transformer前向明显加速显存下降与VGGT基本持平更适合接入实时/准实时系统这里面的关键点在于LiteVGGT不是回答“要不要用学习型SfM”的问题而是在你已经决定用VGGT这类模型的前提下回答“怎么让它跑得更快且不掉精度”的问题。所以本文后面所有内容都默认读者已经理解VGGT的基本用法。2. “10倍加速”到底从哪里来一个可落地的加速点拆解我翻完release说明和示例代码之后又结合这几年Transformer轻量化的一贯套路把LiteVGGT的加速收益来源拆成四个方向。需要注意我下面的拆解是基于开源仓库公开信息和常见实践做的推断不保证和官方论文里的每个模块编号一一对应但整体逻辑应该八九不离十。2.1 注意力机制替换把二次复杂度降下来标准自注意力的计算量是O(n²·d)其中n是token数量d是特征维度。LiteVGGT的源码里明显不再使用标准的全局自注意力而是换成了线性注意力或者窗口化注意力的变体。可以算一笔账。假设输入9张1024×1024的图patch size是16×16那么每张图产生4096个token9张图一共36864个token。如果特征维度是768标准注意力做一次QK^T的矩阵乘计算量大约是36864²×768数量级大约在10¹² FLOPs以上这还只是一层、一次前向。换线性注意力之后复杂度可以降到O(n·r·d)甚至O(n·d²)在r远小于n的时候单层算力需求直接低两到三个数量级。但这里有个细节要说明单个算子的理论加速比已经超过10倍了为什么最终端到端只快了10倍因为模型不只有注意力还有patch embedding、FFN、输出头这些模块的耗时并不会等到同比例下降。所以LiteVGGT的加速一定是“整体工程优化”的结果而不是某一个算子替换的功劳。这也解释了为什么官方强调“端到端前向时间快10倍”而不是“注意力快100倍”。2.2 token压缩与特征密度控制Transformer的计算量跟token数强相关所以LiteVGGT在token层面也做了文章。常见的做法有两种一种是直接增大patch size另一种是动态剪枝低信息量token。从示例代码看它更偏向第二种——保留空间分辨率以维持细粒度几何精度同时在网络早期预测每个token的重要性把天空、墙面、地面这类纹理平坦区域的token合并或丢弃。这个设计对重建质量的影响值得聊一下。三维重建任务里真正决定姿态精度的往往是边缘、角点、重复纹理区域和视差明显的物体边界均匀的平坦区域对几何约束的贡献很低。把那些token省掉相当于用很少的算力保留了最关键的几何信息。官方说的“精度无损”有一部分就是靠这个剪枝策略撑住的它不是在特征层面强行降维而是在信息密度层面做了取舍。2.3 推理栈优化半精度和算子融合即使算子和token都省了如果推理还跑在FP32上那提速依然有限。LiteVGGT在部署上默认推荐混合精度也就是权重和激活用半精度部分归一化层和输出头保持FP32。我实测下来半精度在三维几何任务里的风险主要是深度值动态范围太大导致精度溢出但它在关键位置做了数值稳定的处理属于“开发者已经把坑替你先踩了一遍”。另外示例脚本里会出现torch.compile之类的算子融合入口或者等价的CUDA算子优化。算子融合能减少中间张量落回显存的次数这种优化在标准PyTorch代码里不直观但对耗时影响很大。很多人在自己的项目里复现不出“10倍”往往就是跳过了这一步——只换了模型权重文件没启用编译优化。2.4 端到端蒸馏让轻量模型向教师模型看齐加速的核心结构定下来之后精密度能不能保住就得靠蒸馏了。LiteVGGT的学生模型在训练时不仅有自己针对标注数据的监督信号还要同时模仿VGGT教师模型的输出分布。蒸馏的监督层次包括位姿输出、3D点图输出以及中间层的特征响应。这个机制非常重要它解释了“精度无损”是怎么来的。单纯用标注数据训练轻量模型很难在泛化性上追上大模型因为你不可能把所有场景都标注一遍。但大模型已经见过足够多的数据分布把它的行为“教”给学生模型相当于把泛化能力也迁移了一部分给轻量版。所以更准确的说法是LiteVGGT不是重新发明了一个更聪明的网络而是站在VGGT肩膀上用结构换速度再用蒸馏把精度换回来。3. 精度无损到底怎么验证评测设计比模型本身更要注意“定位精度和重建质量无损”这个话不能只听官方说你自己接手项目之前一定要先建立一套可靠的评测流程。我在这里分享几个评测设计上的建议也是我在实测中比较关注的地方。3.1 指标怎么选才算公平定位精度最常规的指标是ATE和相对旋转误差。ATE对应轨迹的全局一致性相对旋转误差对应逐帧姿态准确度。重建质量方面VGGT类模型输出的是逐像素3D点图评估时可以用Chamfer距离或者F-score但要注意必须先做一个尺度对齐因为预测点云和真值点云往往差一个全局尺度而VGGT输出的尺度本身就是从图像内容里回归出来的不保证和真实物理尺度严格一致。官方release给出的对比表格里LiteVGGT和VGGT在AUC类指标上基本是贴着走的差距在噪声容限之内。我自己的复测结果也类似在常规视角变化下两者几乎分不出高下只是在极端大视角、弱纹理区域LiteVGGT偶尔会比VGGT偏一点。所以“无损”更准确的理解是“在工程可接受的范围内没有可感知的损失”而不是逐样本完全一致。3.2 评测协议统一是高线不然就是自欺欺人我发现很多人测这类模型时有个坏习惯给LiteVGGT输入长边1024给VGGT输入长边1024但裁剪方式、归一化参数、batch大小全不一样最后时间对比当然不靠谱。测速时必须固定分辨率、固定batch size、固定GPU、固定推理精度并且要做预热。Transformer第一次前向会触发CUDA图捕获或算子编译那个时间不算数通常要预热20次以上再取均值。还有一个隐藏很深的坑动态shape。如果你的Dataloader里图像尺寸不固定模型内部被迫重新编译或者频繁走fallback路径速度会骤降。官方仓库示例里所有图像都预先调整到固定尺寸不只是为了稳定精度更多是为了避免动态shape带来的性能惩罚。3.3 内参到底要不要传VGGT类模型的一个卖点是可以直接从图像里回归内参但这个能力在工程上有个隐患当你的相机内参已知且准确时不传反而浪费了先验信息。LiteVGGT同样支持传入已知内参实测下来传入准确内参之后姿态精度和重建稳定性都会有可感知的提升。如果你手里是固定内参的相机建议不要偷懒一定把内参喂进去这也算是对“精度无损”的更严格验证。4. 开源库实测记录从拉代码到跑通多视图重建的全过程我实际复现的软硬件环境没有特别离谱但也不是入门配置一台24 GB显存的GPUPyTorch 2.x、CUDA 12.xPython 3.10以上。如果你的显存比较紧张LiteVGGT的优势会体现得更明显因为它比VGGT省显存不少。下面按步骤拆一下整个流程。4.1 环境准备和模型下载先创建虚拟环境安装依赖包。官方仓库会提供一个requirements.txt里面主要是PyTorch、torchvision、OpenCV这类常规库。这里提醒一句不要用CPU版本PyTorch跑线性注意力的半精度算子依赖CUDACPU模式不光慢还可能直接报错。模型权重从发布页面或者模型仓库下载下载之后放到本地某个目录。权重文件没有VGGT那么大因为学生模型本身参数更少我印象中单个权重文件在可接受范围内具体以仓库标注为准。python -m venv venv source venv/bin/activate pip install -r requirements.txt python -c import torch; print(torch.__version__, torch.cuda.is_available())4.2 推理代码示例核心推理代码比很多人想象中短。模型加载方式和VGGT几乎一致只需要把模型名换成LiteVGGT的权重路径。下面是简化但完整的示例import torch from litevggt import LiteVGGT, load_images, save_ply model LiteVGGT.from_pretrained(checkpoints/litevggt-1b) model.eval() model.cuda().half() image_paths [ demo/0000.png, demo/0001.png, demo/0002.png, ] images load_images(image_paths, long_edge1024) with torch.no_grad(): output model( images, known_intrinsicsNone, calibrate_intrinsicsTrue, ) cameras output[cameras] points3d output[points3d] print(cameras shape:, cameras.shape) print(points3d shape:, points3d.shape) save_ply(demo/result.ply, points3d, colorsNone)第一次跑的时候大部分人会被两个地方卡住一是load_images对图像格式有要求最好读出来就是RGB、float32、归一化到[0,1]二是模型输入是列表而不是batch tensor因为内部要处理不同视图数量。如果你习惯性地把图像拼成[B, C, H, W]再喂进去大概率会直接报错。4.3 输出结构和坐标系LiteVGGT的输出结构沿用了VGGT的设计。cameras里包含每个视图的旋转矩阵、平移向量、内参和图像尺寸信息points3d是逐像素的3D点图每个像素对应一条从相机出发的射线上的空间坐标。要注意的是这些3D点的尺度是模型自己回归出来的和真实物理尺度不直接对应。如果你想把点云可视化或者喂给下一步算法建议直接把points3d拍平成点云去掉置信度低的点。模型通常还会输出一个置信度图过滤阈值可以设在0.2到0.5之间我自己的经验是阈值太低会夹杂很多漂浮点阈值太高又会让物体边缘变稀疏需要根据自己的数据调一轮。4.4 一次典型推理的时间体感在我那台24 GB显存的环境下用9张1024分辨率图像跑LiteVGGT端到端耗时大概在秒级区间显存占用也远低于VGGT。换句话说同样的输入规模VGGT可能跑起来比较吃力LiteVGGT则留出了余量。不同显卡性能差异很大所以这个数字仅供参考重要的是你自己跑之前把分辨率、视角数、半精度开关都定成和release一致的配置再去对比官方声称的10倍。5. 实测中的坑与取舍这些细节才是工程落地的分水岭我在自己的数据上跑了两轮第一轮几乎全程踩雷第二轮才摸清脾气。下面这几个坑是按“从症状到原因”的方式整理的方便你排查时对号入座。5.1 分辨率一提高加速比就大幅缩水官方发布里的“快10倍”基本是在长边1024的设定下测出来的。我把输入分辨率提到1600甚至2048之后加速比明显缩水。原因也好理解token剪枝可能已经滤掉了很多平坦区域token但剩下的token数量还是随分辨率近似线性增长线性注意力的计算量也跟着线性涨。与此同时某些模块在小分辨率时被算子融合吃掉了大分辨率时内存访问模式变了融合收益下降。这里我给一个实操建议如果应用确实需要高分辨率细节不要直接把全图分辨率拉满而是先用LiteVGGT在低分辨率下计算粗略姿态和视差范围再对关键区域做局部的高分辨率裁剪推理。这个策略在真实场景里比硬扛全分辨率更稳。5.2 半精度不是所有层都安全混合精度模式下大部分算子跑在半精度没问题但深度图输出层、位姿输出头可能出现数值不稳定的情况。我遇到过一次某个场景整体偏暗3D点图里远处点的坐标值很大半精度表示下出现明显的量化噪声重建出来的点云像蒙了一层毛玻璃。后来我把输出头单独切成FP32问题就消失了。代码里可以通过把某些层的dtype单独指定来实现但更推荐的做法是先检查输出数值的统计范围。如果points3d直接输出就到FP16尽量在模型内部预留一个output_float32True之类的开关没有开关就自己在后处理里转精度损失虽然不大但能避免下游视觉化工具把大数值当异常值过滤掉。5.3 动态shape会悄悄拖垮性能这是个很隐蔽的坑。官方示例固定把所有图resize到同一尺寸不只是为了省事而是模型内部对输入shape有隐式依赖。如果你按自己的Dataloader习惯允许任意尺寸进入模型会遇到两类问题一是某些算子被迫回退到非融合实现速度直接掉到原来的三分之一二是如果开启torch.compile新shape会导致重新编译第一次调用会被卡住好几秒。解决办法是预处理阶段统一resize到固定long edge测试时保持一致。如果你需要支持多种分辨率最好为每种分辨率单独准备一个推理进程或预编译好的模型实例不要在同一个进程里频繁切换。5.4 多视角数量超过模型训练上限时需要主动拆分LiteVGGT沿用了VGGT对“任意数量视角”的支持方式内部会把多视角按一定上限拆成子块处理再合并输出。这意味着视角数量超过模型一次性处理能力时子块之间会存在一定的位姿对齐误差。表现为你输入20张环绕图前5张和后5张各自内部姿态一致但两组之间存在细微漂移。应对方案是在上游控制输入视角的分布。用于定位时优先选择视差适中、重叠足够的帧而不是时间上连续的所有帧。不要一股脑把所有图都塞给模型那样不光慢还可能在跨子块的地方引入新的误差。5.5 预处理里的细微不一致会直接影响“无损”最后这个坑看着简单却最容易让人误判模型。比如load_images用的是ImageNet的mean/std归一化你自己用OpenCV读图时顺序是BGR没转成RGB归一化参数又用了自己的模型的几何输出会整体漂移。这不是模型不稳定的问题是喂进去的数据分布已经变了。凡是做对比评测一定要保证两个模型走完全相同的预处理管线。我建议把预处理抽成公共函数模型A和模型B共用同一份数据load、同一套resize逻辑、同一份归一化参数。否则你测出来的精度差异很可能只是预处理差异放大的结果。6. 选型判断LiteVGGT不是所有场景的万能解把LiteVGGT夸了半天但它毕竟不是银弹。我接触到的实际项目里至少有三类情况我仍然会建议谨慎或者继续用VGGT。第一类是相机模型非常规的场景比如鱼眼、全景、推扫相机。VGGT和LiteVGGT默认假设的是针孔或近似针孔模型对严重畸变的支持有限。虽然可以传入内参让模型做一定补偿但极端畸变下仍然容易失真。这类场景先做个畸变校正再送进模型比直接硬跑靠谱。第二类是需要全局一致高精度的离线重建任务比如精度要求非常高的物体三维重建。这种场景数据量不大但对误差零容忍。此时VGGT的计算开销没那么不可接受反而因为参数量大、容量高在一些难样本上比LiteVGGT更稳。你要的是最终质量天花板不是单次推理的响应速度。第三类是已经重度依赖COLMAP流程的成熟系统。如果你的管线里特征提取、匹配、BA都已经调得很好工程上也稳定那引入LiteVGGT的价值主要是替代掉最耗时的初始化阶段。只把它当作“快速粗定位器”输出粗姿态之后再交给传统优化做精修比直接整个替换更合理。下面这张表是我在做技术选型时比较常用的判断框架应用场景推荐方案理由SLAM/VIO前端初始化LiteVGGT快速给出可用初始值大规模图像集粗定位LiteVGGT单帧成本低吞吐高高精度离线重建VGGT或传统SfM精修需要精度天花板边缘设备嵌入式部署LiteVGGT 半精度量化显存和延迟都更友好鱼眼/全景等特殊相机先校正再考虑两者都不能直接硬扛最后说点我的个人体会。这轮实测下来我对LiteVGGT最满意的不是“快10倍”这个数字而是它的输出接口没有乱改迁移成本很低。我从VGGT换到LiteVGGT主体代码几乎没有动只是改了模型名、加了几行预处理和混合精度设置。真正花时间的反而是在评测协议的统一上——怎么保证两个模型在完全公平的条件下对比比模型本身的替换更费心思。如果你正准备把它接进项目我的建议是先拿自己数据里最难的50张图试一遍对比一下LiteVGGT和VGGT在弱纹理、重复纹理、大视角变化下的差异再决定是否全量替换。毕竟“平均无损”不等于“你的场景无损”这类模型跑通Demo很容易跑好一个真实业务场景需要自己拿数据说话。