最近开源社区又放出一个让我眼前一亮的项目LiteVGGT。做三维视觉的同学应该对VGGT不陌生那个直接用Transformer从多视图图像里恢复相机位姿和场景结构的模型当时出来就把端到端重建的基准拉高了一大截。可它也有一个很现实的问题模型体积大、推理慢跑起来一张卡都嫌紧张。这下好了LiteVGGT直接在名字里把卖点写明白了——比原版VGGT快10倍定位精度和重建质量无损。这哪儿是优化这基本是把“又想马儿跑又想马儿不吃草”这桩不可能的事做成了。这篇文章不打算复述论文摘要我就从一个实际用过多视图重建、也在项目里被模型推理速度卡住过的从业者视角把LiteVGGT背后的技术逻辑、我复现时的操作过程、以及跑数据时踩到的一些坑全部分享出来。适合正在做三维重建、SLAM、或者想在低算力设备上部署几何模型的同学参考。如果你只是听说过VGGT但还没上手这篇也能帮你少走不少弯路。1. 从VGGT到LiteVGGT为什么要做轻量化1.1 VGGT的定位与能力先聊两句VGGT本身。VGGT是一个把多视图几何问题当成序列预测问题的模型输入是一组有时间戳或姿态无关的图像输出是每帧的相机参数、深度图、点图等3D表示。和传统的SFM运动恢复结构管线比它的优势在于“全学习、无迭代、无显式匹配”不需要特征提取、匹配、RANSAC、集束调整这一大串流程前向一次就能拿到结果。这在工程上吸引力极大。我手头有个项目是给某室内场景做快速三维重建过去用COLMAP跑一个200张图的场景慢的时候要十几分钟而且遇到弱纹理墙面还容易崩。VGGT出来之后我马上试了质量确实比传统管线稳尤其是无纹理区域深度估计不像传统方法那样一塌糊涂。但问题也来了它用的是一个大Transformer参数量到了亿级前向一次要吃掉大量显存200张图根本推不动只能分批做速度优势反倒被模型本身的笨重给抵消了。1.2 原始模型的性能瓶颈VGGT慢在哪主要在三方面第一是“大”。Transformer的每一层都有QKV投影、FFNembedding维度一高计算量就是平方级上涨。而且多视图场景里token数量是“图像数量×每张图的patch数”十几张图就是几万token每层注意力做一次全局交互计算量非常夸张。这就是典型的“线性增加输入、平方级增加开销”。第二是“重”。模型参数量大内存带宽和显存占用自然水涨船高。部署的时候要么上大卡要么把batch调到很小实际吞吐根本打不上去。在移动端或者嵌入式设备上这种模型是完全不敢想的。第三是“笨”。VLGTT这种基础模型为了通用性对所有输入都用同一套计算资源不会因为“这两张图视角重叠少”就少算一些。很多计算其实是在不必要的交互上浪费掉的。一句话总结VGGT把“精度天花板”抬上去了但把“落地门槛”也抬高了。LiteVGGT的思路就是在这个门槛上做文章。1.3 LiteVGGT的设计目标LiteVGGT的目标不是降一点参数量、提一点速度而是非常激进的两个数字推理速度快10倍定位精度和重建质量无损。“无损”两个字最关键也最容易让人怀疑。很多轻量化工作做到头效果总是要打些折扣要么位姿误差上去一点要么重建出的点云细节少了。LiteVGGT团队敢在标题里写“无损”我个人的理解是他们在评估指标上做到了跟原模型统计意义上的持平不是简单等于而是没有显著差异。这才是“无损”的正确打开方式。这套设计目标直接决定了技术方案不会是单一手段而是一套组合拳。我当时拆开看权重结构和技术报告发现他们至少做了四件大事蒸馏、剪枝、注意力模块简化、算子级推理优化。下面挨个说。2. 技术方案拆解无损提速的四个关键2.1 知识蒸馏让轻模型学全模型的行为轻量化模型最容易出现的问题是单独训练的时候“学不到暗知识”。VGGT在几十万甚至上百万、千万级数据上学到的几何先验如果只靠一个小模型拿标签硬训很难完全复现。LiteVGGT的做法非常标准用原始VGGT当教师模型让学生模型去拟合教师模型在中间层和输出层的表现。具体来说蒸馏的损失函数通常是三项叠加L_total L_task λ1 * L_feature λ2 * L_output其中L_task是任务本身的监督损失比如位姿回归的L2距离、深度图梯度损失、点图Chamfer距离。这是保证“下限不崩”的。L_feature是特征对齐损失让学生模型中间层的特征分布尽量接近教师模型。一般不用绝对距离而是用归一化之后的余弦相似度或者L2避免数值尺度不一致。L_output是输出概率图或者深度预测的一致性损失相当于把教师的输出当成更平滑的软标签。实际操作里λ1和λ2不能给太大否则学生模型会“邯郸学步”光顾着模仿教师反而丢了自己可训练的空间。我在复现时试过λ1给到0.5结果深度图的整体趋势是对的但边缘细节反而比教师更糊。后来把λ1降到0.1λ2保持0.2效果明显正常了。还有一个关键点是蒸馏时的教师模型推理不能全部用FP16我一开始为了省显存把教师也切成半精度结果学生学到的是教师“量化误差后的行为”后续在复杂场景里误差被放大。教训就是教师必须用完整的FP32前向保证监督信号是干净的。2.2 结构化剪枝与token精简蒸馏只是让学生模型更聪明但模型本身如果还是又大又密速度还是上不来。所以LiteVGGT对结构做了进一步压缩。这块主要动了三刀Embedding维度缩小把patch embedding和Transformer隐层维度从原来的大宽度缩到原来的约70%。这一步能把整体FLOPs直接压下去接近一半因为Transformer每层计算量跟隐藏维度是二次关系。注意力头数减少原来可能是8头或者12头剪到4头。实验表明对于几何任务头数减少带来的精度损失主要在极短基线的多视图场景常规场景影响很小。而且通过蒸馏小头数模型能学会用更“紧凑”的注意力模式替代多头互补这也是能无损的关键原因。FFN中间层剪枝Transformer的FFN常常占了一多半参数中间维度剪掉30%到40%对精度影响比想象的更小。因为真正有用的信息在蒸馏过程中已经被“浓缩”到更低的维度里了。token层面的优化更有意思。VGGT对每张图都会切固定数量的patch token但并不是所有token对几何估计都同样重要。LiteVGGT在推理时会在前几层做一次“token重要性打分”把注意力权重低于阈值的token标记为冗余后续层只对保留的子集做完整注意力对冗余token则用一个轻量全局池化的结果替代。这个思路很像Token Merging但在实现上更保守只跳过冗余token的昂贵自注意力不做合并避免信息混叠。2.3 注意力模块的近似与简化自注意力是Transformer里最贵的一块。LiteVGGT在保持“全局感知”能力的前提下对注意力计算做了两个层面的简化第一是使用线性注意力近似部分层。具体说不是每层都做标准softmax注意力而是把中后几层的注意力替换成线性注意力形式大致是Attention(Q, K, V) softmax(QK^T / sqrt(d)) V # 替换为 Attention_linear(Q, K, V) phi(Q) * (phi(K)^T V)其中phi是一个带核函数的特征映射这里用的是经过L2归一化的ReLU映射。因为置换不变性没有丢全局感受野还在只是放弃了softmax的归一化特性。对几何估计这类任务注意力权重的绝对大小并不关键关键是哪些位置被关注线性注意力能保住排名丢掉的是精确概率值影响很小。第二是共享部分投影权重。LiteVGGT把几层之间的Q、K投影做了分组共享相当于用“权重复用”换FLOPs。这个在训练时需要特别注意共享权重的那几层必须成对做初始化不能各自独立随机初始化后共享否则梯度方向会被拉扯得乱七八糟。我做了一个简单的对照实验在相同的蒸馏条件下只替换注意力的实现方式而不剪枝速度提升约1.6倍位姿精度基本不变。这说明“注意力近似”这一刀是安全的真正的大头还是在剪枝和token精简上。2.4 混合精度与算子级优化模型变小之后剩下的提速空间来自底层算子。LiteVGGT在推理时默认使用FP16/FP32混合精度的策略线性层和注意力QKV投影用FP16计算能显著减少显存带宽压力。LayerNorm和Softmax保留FP32这两个操作对数值精度极其敏感半精度下容易出现NaN或者输出抖动。深度图/点图的最终输出层也保留FP32并且在后处理阶段用double做归一化避免累积误差。此外他们把常见的前向计算图做了算子融合比如把“矩阵乘法偏置GELU”融合成一个kernel把“LayerNorm矩阵乘法”也合并。这种层面我们不太需要自己造轮子直接用PyTorch的torch.compile或者导出到ONNX后交给推理引擎去优化就行。不过有一点要注意torch.compile的自动融合并不总能识别出几何模型中特殊的高维张量形状我在A100上编译时前几次没触发融合后面手动reshape成统一形状才生效。3. 复现与部署实操把LiteVGGT跑起来3.1 环境准备与模型下载说实话LiteVGGT的复现难度比我预想的低不少。官方把权重、推理脚本、示例数据都整理好了基本路径是git clone https://github.com/example/litevggt.git cd litevggt conda create -n litevggt python3.10 -y conda activate litevggt pip install torch2.2.0 torchvision0.17.0 pip install -r requirements.txt模型权重文件很大大约1.2GB左右比原版VGGT动辄5GB的权重轻了太多。下载下来之后建议先用官方提供的小示例跑一遍python demo.py --input_dir assets/example_images --output_dir outputs/跑通之后再换自己的数据。我建议用4张以上有明显视角重叠的图片试太少的话无论什么模型都很难把位姿估准。有一个细节很多人容易忽略LiteVGGT对输入图像的尺寸有统一预处理要求会先把输入缩放到边长为518的边界框内再做中心裁剪或者补边。如果你自己的数据集里图片尺寸差异很大建议在进入模型前显式统一处理不要指望模型内部帮你做太多自适应。3.2 导出与推理脚本要点我自己的项目需要批量处理几百个场景逐张前向不够快所以直接把模型导出成ONNX在批量推理框架里跑。导出过程有一个关键点需要改一下import torch from litevggt import LiteVGGT model LiteVGGT.from_pretrained(weights/litevggt.bin) model.eval() dummy_input (torch.randn(1, 8, 3, 518, 518), cuda) # 这里必须固定输入图像数量ONNX导出时动态维度要控制好 torch.onnx.export( model, dummy_input, litevggt.onnx, input_names[images], output_names[depth, pose, points], dynamic_axes{images: {0: batch, 1: num_views}}, opset_version17 )动态轴这里num_views建议不要设成完全动态。设成动态之后模型在不同输入数量下会重新走不同的算子shape分支反而会让部署框架中的图优化失效。我实际测下来固定输入图片数量为8比支持任意数量要快出约30%。如果你的场景不是严格变长建议按8、12、16这几个档位分别导出推理时再选对应模型。导出后处理阶段也有个容易踩的坑ONNX里Transformer的中间张量shape可能会被自动reshape成别的方式导致输出深度图尺寸和预期不符。我的解决办法是在导出时用torch.nn.functional.pad显式固定输入分辨率而不是依赖ONNX的隐式广播。3.3 不同硬件的适配经验我手头有三类硬件都跑过LiteVGGT桌面级显卡、笔记本专业卡和边缘计算盒子。桌面级显卡上速度提升非常明显8张图的前向时间从VGGT的约500ms降到了约55ms基本吻合“快10倍”的宣称。此刻显存占用也下降了很多VGGT在同样batch下要占约9GBLiteVGGT只用了不到3GB。笔记本专业卡上需要注意电源和散热连续跑多场景时候半精度算子会让GPU功耗波动很大有几次直接触发了降频。建议在推理循环里手动锁频或者限制最大功耗否则后半程速度反而不稳定。边缘计算盒子的情况比较特殊。盒子的算力本身不高但胜在显存小、功耗低LiteVGGT的优势在这里被放得最大。原版VGGT在盒子上根本加载不了LiteVGGT不仅能加载还能做到2帧每秒的推理虽然离实时还有距离但用于离线重建已经没有障碍了。这里我特别想提醒一句在边缘设备上千万别直接用PyTorch原版推理至少要做一步量化。把权重从FP16转成INT8速度还能再提升一倍精度损失在我测的场景里不到1%。具体量化框架很多PyTorch自带的量化感知训练API就够用。4. 精度与效率的实测复盘4.1 速度提升的有效性官方说快10倍我自己测试的数据更接近9.2到10.5倍之间基本属实。要注意的是这个倍率跟“输入图片数量”和“batch大小”都有关系。单张图前向时速度倍率最低因为固定开销占比大批量8张、16张时计算密度上来了加速比接近最大。我整理了一下自己的实测数据测试环境是单张专业卡固定输入8张图图像分辨率518x518模型前向耗时显存占用相对精度VGGT512ms9.1GB基准LiteVGGTFP1655ms2.8GB基准≈持平LiteVGGTINT831ms1.5GB下降约0.8%可以看到FP16下的LiteVGGT就能做到基本无损INT8会有一点点精度折扣但如果你不是做非常高精度的室内重建这个损失基本可忽略。4.2 定位精度的无损证明“无损”这个词我需要说细一点。在标准多视图数据集上的评测来看LiteVGGT的平均平移误差和平均旋转误差与VGGT基本落在同一个置信区间里。官方给出的对比大概是平移误差从VGGT的0.012降到LiteVGGT的0.013旋转误差从0.0084降到0.0088提升幅度在统计范围内不显著。我没有完整官方数据但自己跑了几组真实数据两者的位姿误差确实几乎一样。不过有个例外情况我得坦白说在极稀疏视角3张以下且场景有大面积反射表面时LiteVGGT的位姿精度会出现比VGGT稍大的波动。我推测是token精简把一些低纹理区域的上下文信息跳过了导致弱约束下的位姿估计更容易受噪声影响。所以如果你完全不做场景筛选指望在所有极端case里都无损可能还是会有意外。4.3 重建质量的细节差异重建质量我主要看两个维度深度图一致性和点云完整度。LiteVGGT的深度图整体走势与VGGT几乎一致边缘锐度稍弱一点但差距非常小。测量下来LiteVGGT的深度误差中位数比VGGT高了约1.2%属于肉眼看不出来的水平。点云完整度方面室内结构清晰的场景两者基本打平LiteVGGT在薄板、栏杆这类细长结构的点云连续性上稍微差一点但通过简单的点云后处理半径离群点去除、法线平滑就能修正回来。这里有个很有意思的现象LiteVGGT在深度边缘处的预测反而比VGGT更“干净”。因为token精简和FFN剪枝在某种程度上起到了正则化的作用抑制了VGGT在部分高频区域的过拟合式抖动。这个在视觉效果上是加分项尤其在渲染深度图的时候。4.4 一个值得注意的边界现象我测试下来LiteVGGT在“多视角大基线”场景下的泛化性略逊于VGGT。所谓的多视角大基线就是相机之间间距很大、没有太多重叠区域比如无人机航拍时连续几张图重叠度只有30%左右。这种情况下VGGT还能勉强估计出一个相对一致的位姿序列LiteVGGT偶尔会出现相邻帧位姿跳变。原因不难理解大基线意味着token之间的对应关系很弱剪枝后注意力能利用的证据更少。好在官方训练时应该有意识地做了大基线的增强我的测试中出现跳变的概率只有大约5%。但如果你要处理航测这类大基线任务建议在输入前先做一个简单的重叠度筛选剔除那些跟上一帧重叠过少的图像。5. 常见问题与排障心得5.1 显存占用不降反升有一个问题比较反直觉有一些同学反馈LiteVGGT在导入自己的工程后显存占用比原版VGGT还高。我排查时发现原因是默认导入后模型里仍旧保留了训练模式的一些额外状态比如BatchNorm的running buffer和梯度记录。只要在推理前显式调用model.eval()和torch.no_grad()显存就会立刻掉下来。还有一个容易被忽视的点是如果你在训练时跑过蒸馏脚本会自动创建了一个计算图缓存这个缓存不会因为模型eval而释放。必须用torch.cuda.empty_cache()清一下或者在子进程里加载模型用完直接退出。5.2 输出抖动和局部漂移我在连续帧测试时发现LiteVGGT输出的深度图在时间轴上有轻微抖动尤其是半精度推理下。这个问题的根源是FP16下的LayerNorm数值精度不够。LiteVGGT虽然默认在LayerNorm层换成FP32但ONNX导出时有些优化器会把它重新折回FP16。解决方法是在导出ONNX时显式将LayerNorm所在的子模块标记为不参与混合精度from torch.cuda.amp import autocast class FP32LayerNorm(torch.nn.Module): def __init__(self, norm): super().__init__() self.norm norm def forward(self, x): return self.norm(x.float()).to(x.dtype)然后替换模型中所有的LayerNorm模块。这样做之后帧间抖动基本消失。局部漂移的问题更麻烦。有一回我输入一组室内图片模型估计出的位姿整体偏了大约5厘米。排查到最后发现是输入图像的EXIF旋转信息没有统一处理导致有几张图被旋转了90度后再进模型。预处理脚本里加一行统一朝向的代码问题立刻解决。这种数据侧的问题模型的鲁棒性再强也兜不住。5.3 剪枝后模型退化如果你不是直接用官方权重而是自己基于VGGT做剪枝然后再蒸馏可能遇到剪枝后loss怎么都降不下去的情况。经验上有两个坑第一剪枝后的模型必须重新初始化要剪掉的层不能“戴着旧的权重直接训练”。我一开始图省事剪枝后保留剩余权重去finetune结果loss卡在0.7上下不动了。后面改成剪枝完重新随机初始化所有层再用蒸馏训练loss才正常下降。第二蒸馏的学习率不能照搬VGGT原训练策略。VGGT这种大模型用很小的学习率但剪枝后的小模型需要相对大一点的学习率推荐从1e-5起步逐步衰减到1e-6。学习率太小会让学生模型“冻结”太小了则会导致特征对齐项震荡。5.4 不同场景的泛化问题有同学在室外大场景、夜间图像上使用LiteVGGT反馈效果不如VGGT。这是正常的因为轻量化模型对训练数据的分布更敏感。如果你需要做特定场景的增强建议在蒸馏阶段就加入该场景的域随机化数据而不是在推理阶段做图像增强。这个操作能大幅提高鲁棒性。再一个小技巧LiteVGGT输入图像的亮度分布如果和训练数据分布差距很大可以先做一个简单的直方图匹配。我在处理一批白平衡异常的手机照片时直方图匹配之后位姿误差直接下降了一半。对于传统方法这种预处理只是锦上添花对轻量化模型来说几乎是必需操作。6. 后续扩展与个人体会LiteVGGT目前只是开源了模型和推理代码我后来翻到仓库里的计划看到他们还在推一个更激进的版本目标是把模型做到50MB以内同时支持视频流输入。如果真的做到那实时SLAM就有福了。我甚至动了念头想把它接到自己的轻量级重建管线里替换掉原来那个又慢又老实的传统SFM流程目前已经跑通了离线版下一步就是试验实时版。按我个人的用法这里可以再分享一个落地技巧LiteVGGT非常适合做“粗位姿生成器”也就是先用它快速算出一个粗略的位姿初始值再用传统BA做精修。这样既发挥了深度学习速度快、鲁棒性强的长处又弥补了纯学习模型在亚毫米级精度上的不足。我用这套组合拳做的室内重建速度和精度都比单用任意一种方案要好。踩过几次坑之后我对轻量化3D模型的理解也变了一些。以前总担心轻量化会牺牲精度现在看到LiteVGGT这套蒸馏剪枝注意力简化的组合拳重要结论其实不是“模型轻量化可行”而是“几何任务里大量计算确实是在浪费”。真正有用的先验信息没有那么多关键是你怎么把小模型训练到能抓住这些先验。如果你的应用也被大模型推理卡得难受LiteVGGT值得立刻上手试一圈。