从去年开始,3D高斯泼溅(3DGS)几乎成了重建和渲染领域绕不开的关键词。静态场景用一组3D高斯就能实时高保真渲染,逼得NeRF系列的工作退到了角落里。但真正上手做过项目的人心里都清楚,3DGS在静态场景里很能打,一旦碰到动态场景——人物动作、物体形变、拓扑变化——问题就全冒出来了:时间上不稳定、遮挡处容易飘、形变建模经常把画面学糊掉。最近英伟达在ICLR‘26放出的Lyra,正是冲着这个痛处去的,而且它用的路子很有意思:蒸馏。不是把大模型压小那种蒸馏,而是把“教师模型”里的重建先验蒸馏进3DGS这个学生表示里,让静态和动态场景重建都能拿到一个新的SOTA水平。这篇文章我想从项目定位、蒸馏管道设计、复现要点到踩坑经验,完整拆一遍Lyra到底做了什么,以及你该怎么把它用起来。
1. 先看定位:Lyra解决的是3DGS的“最后一公里”
1.1 静态重建已经很卷,但“够用”不等于“好用”
静态场景的3DGS重建,流程其实已经被社区跑得很顺了。拿到一组多视角图片,用COLMAP算出相机位姿和稀疏点云,把点云作为3D高斯的初始化,然后通过可微光栅化不断优化每个高斯的位置、协方差、颜色球谐系数和不透明度。渲染速度快、画质高,尤其是和NeRF比,训练时间从小时级压到分钟级,推理更是实时。
但深入做过场景重建的人会有另一个感觉:3DGS在纹理稀疏、视角覆盖不全、反光或半透明材质上仍然容易翻车。它本质上是一个显式点云模型的参数化表示,优化过程非常依赖“足够的观测证据”。一旦某个区域各视角都不太能看见,高斯就有可能在那个区域乱长,产生“浮空物”或者雾状伪影。这就是所谓的最后一公里问题——大部分场景都重建得很好,边缘和疑难区域却总需要人工修复。
Lyra的思路就是把这个“最后一公里”交给教师模型去兜底。教师网络不需要和3DGS争速度,它可以用更强的网络容量、更全局的视野去估计场景结构和外观分布,然后把这些估计结果转化为监督信号,引导3DGS去学。这样学生继续保有时间上的实时渲染能力,但学到了教师模型的泛化先验,疑难区域就不容易学歪了。
1.2 动态场景才是3DGS真正的分水岭
如果说静态场景的3DGS是基本盘,动态场景就是硬骨头。目前主流动线基本分几类:一类是逐帧优化独立的3DGS,每帧都重建一组高斯,这样能保证单帧质量但完全没时序一致性,渲染出来闪烁得没法看;另一类是在规范空间里维护一组高斯,再用一个变形网络把它映射到每个时间帧,这套在拓扑变化不大时效果尚可,但复杂度上来了,形变幅度一大就容易糊;还有一类干脆把时间直接加进高斯参数里做4D高斯泼溅,思路新颖但训练开销和内存占用都很惊人。
我自己的实践感受是,动态场景真正的难点不是单帧重建,而是运动轨迹的连续性和交互遮挡的处理。一个很简单的例子:一个人走路,手臂前后摆动,前一帧还能看到的手肘,下一帧被身体挡住了。如果模型没有对运动趋势的理解,它在这种区域就会产生抖动甚至鬼影。别的像素级的loss很难解决这个问题,因为每一帧的信息是局部且不完整的。
Lyra在这种场景下选择蒸馏,实际上是在给动态重建加一个“全局运动先验”。教师网络可以看到多帧甚至整个视频片段,它能比逐帧学生网络更准确地估计“这个点下一帧应该在哪”。学生网络不需要自己从头悟出运动规律,只需要在教师给的软标签指导下把高斯参数调整好。这种“全局教局部”的关系,天然适合动态场景。
1.3 蒸馏为什么能同时解决静态和动态的毛病
说句实话,第一次看到“蒸馏3D高斯泼溅”这个表述时,我也愣了一下——传统知识蒸馏一般用于模型压缩,把大模型的泛化能力迁移到小模型上,但Lyra并不是要拿一个轻量3DGS替代重型网络,而是要同时提高3DGS的鲁棒性和保真度。
这里面的关键认知是:蒸馏并不只是“大模型教小模型”,本质上是“强先验教师给弱泛化学生注入知识”。静态场景里,教师用多视图几何一贯性的表示去规范学生的几何分布;动态场景里,教师用跨帧运动特征去约束学生的时序一致性。两个场景共享同一套蒸馏框架,区别只在于教师处理的是空间维度还是时空维度。
这也解释了为什么Lyra能被称作“静态和动态场景重建新SOTA”而不是又一个单纯的动态3DGS变体——它把被很多人当成“模型压缩工具”的蒸馏,重新定义成了“表示增强工具”。我认为这个视角的转变,比某一个具体网络模块更重要。
2. 方法拆解:Lyra的蒸馏管道是怎么搭起来的
2.1 教师网络怎么选:2D先验还是3D先验
蒸馏框架的第一件事是定教师。从题目信息和英伟达一贯的技术路线来看,Lyra的教师不会是一个简单的预训练分类器,而是具备强大场景理解能力的重建先验模型。这里大体上有两条路线可选,Lyra的做法也基本沿着这两条路线做了融合:
- 以2D扩散模型为代表的图像/视频先验模型。这类模型在互联网级数据上训练过,知道真实世界的图像长什么样、视频帧间是怎么变的。它们能提供非常强的外观先验和运动先验,尤其擅长处理遮挡、模糊这些3DGS容易翻车的区域。
- 以多视图立体匹配为主的3D先验模型(类似DUSt3R/MASt3R这类)。它们直接输出几何相关的估计,比如深度、点云对应关系,比2D先验更“贴地气”,能直接用来约束3D高斯的位置分布。
Lyra的做法在我的理解里是两路都用了:3D先验负责给学生提供几何骨架,2D/视频先验负责提供外观和时序纹理信息。这样教师输出的不是一个单一信号,而是一个多层次的先验包——既管高斯基元的位置漂移,也管球谐系数的颜色预测。
过一遍整体流程就是:输入一组图像或一个视频片段,教师模型分别产出geometry prior和appearance/motion prior,这些prior会转换成伪标签(pseudo-label)或者特征对齐信号,再和学生3DGS的渲染结果做对比。学生网络在整个过程中始终是一个可微的3DGS光栅化器,它不直接复制教师网络的权重,而是让教师知识通过loss回流到高斯参数上。
2.2 学生网络与蒸馏信号:3DGS在哪个位置“被教”
蒸馏信号往3DGS哪里加,决定了框架的有效性。3DGS的参数无非就是坐标、协方差、不透明度、球谐系数,外加动态场景里的变形网络。如果蒸馏信号不加选择地平均分配到所有参数上,会很容易把模型搞乱——有的参数需要强约束,有的参数需要自由优化。
从实操角度讲,我更倾向把蒸馏信号分成几何支路和外观支路。几何支路直接监督3D高斯中心位置和不透明度,目标是让高斯分布和教师模型估计的场景结构对齐。这个监督在静态场景里尤其重要,因为它能抑制漂浮高斯;在动态场景里,它约束的是形变网络预测的位移场不能过于离谱。
外观支路监督的是球谐系数经过光栅化后的像素输出。注意,这里不是直接监督球谐系数本身,而是监督渲染后的图像和教师模型给出的伪图像之间的差异。因为球谐系数和最终颜色是高度非线性的关系,直接回归系数容易顾此失彼,走渲染域监督更稳。
另一个细节是,蒸馏信号应该加在哪个特征层级。如果你用过风格迁移或者感知损失就会知道,像素级L2 loss在空间细节上很锐利,但语义和结构感不足。Lyra的蒸馏框架在这个问题上实际上是分层的——低层特征对比边缘和纹理,高层特征对比结构布局,时间维度上再额外对比帧间运动一致性。层层叠上去之后,学生3DGS学到的不只是“这帧该长什么样”,而是“这个场景在这个运动状态下应该长什么样”。
2.3 静态与动态的统一:同一个loss怎么覆盖不同场景
Lyra在命名上强调“静态和动态场景重建新SOTA”,说的是一个框架通吃两种场景,而不是分别出两套模型。这个设计很聪明,因为现实中很多重建场景是混合的——背景静止,前景在动。如果静态和动态分开建模,融合时还得处理边界和交互;统一建模则一次性把这个麻烦绕过去了。
统一框架的核心手段是“规范空间+变形场”的标准搭配。模型维护一组规范空间中的3D高斯,描述静态场景结构和动态目标的平均姿态;静态区域可以完全不做时间变形,动态区域则通过一个轻量MLP预测每个高斯在当前时间戳的位置偏移和旋转变化。蒸馏教师在这个框架里扮演的职责更集中:它告诉学生规范空间应该长什么样,也告诉学生变形场在每一帧应该把高斯推到哪里。
Loss设计上,静态场景就跑基础的重建loss加几何蒸馏loss,动态场景则额外加时序蒸馏loss和运动平滑正则。同一个网络结构,不同的loss组合,训练起来非常干净。我比较欣赏这个设计,因为实际工程项目里最怕的就是一个需求换一套架构,维护成本极高。Lyra这种设计至少给了一个可用的统一基线,下游按需调整即可。
3. 复现准备:环境、数据与训练参数
3.1 环境和依赖:版本坑比你想象的多
先别急着看模型结构,环境问题上我已经帮你们踩过一遍了。3DGS家族的代码对CUDA版本和PyTorch版本相当敏感,Lyra大概率也是基于diff-gaussian-rasterization这个可微光栅化子模块做的,编译那一步就是第一道坎。
建议直接用conda建一个干净环境,Python版本3.10左右比较稳妥。PyTorch的版本要和你机器上的CUDA驱动匹配好,我的经验是PyTorch 2.1配CUDA 12.1算是一个兼容性比较好的组合。diff-gaussian-rasterization这个子模块需要用CUDA编译器做扩展编译,所以系统一定要装好匹配的nvcc——注意不能只用PyTorch自带的CUDA runtime,还要有完整的CUDA toolkit。
另外,因为Lyra要做蒸馏,训练时通常要加载一个教师模型。教师模型的依赖树和学生部分不完全重叠,可能出现某个库的版本冲突。我建议把教师模型单独放在一个子环境里先跑通推理,确认能输出伪标签,再回到主环境做联合训练。别小看这一步,我遇到过好几次因为OpenCV和某些3D处理库的版本不一致,导致训练中途直接崩掉的情况。
3.2 数据准备:静态场景和动态场景的数据管线
静态场景的数据准备沿用3DGS的标准管线就行。先用COLMAP做特征提取、匹配、稀疏重建,得到相机内外参和稀疏点云。如果你用的是公开数据集,比如Mip-NeRF 360或者Tanks & Temples,记得要统一成3DGS能识别的格式——最关键的是把COLMAP格式的相机参数转换成3DGS内部使用的相机参数组织形式,这一步出错后面全部白搭。
动态场景就复杂一些。常见的数据集格式有D-NeRF那种单相机多时间步拍摄的合成数据,也有HyperNeRF那种多相机同步采集的真实数据。用Lyra这类框架处理时,数据管线里最需要注意的是时间戳对齐。不同视角的相机如果帧率不同步,哪怕是几毫秒的误差,都会让变形网络学到自相矛盾的运动轨迹。处理办法是先对视频流做时间插值对齐,然后统一生成训练样本的时间索引。方法不高级,但能明显减少动态场景训练的鬼影问题。
相对路径的处理也要提一下。3DGS的代码对路径很敏感,训练和测试阶段如果路径不对,要么加载不上checkpoint,要么输出的评估结果全是乱码。建议统一用绝对路径引用数据集和输出目录,避免在不同机器上迁移时踩路径坑。
3.3 训练参数与蒸馏权重:让模型真的收敛
训练3DGS本身已经有不少参数调优的技巧,加上蒸馏之后,“怎么让模型收敛”就成了一个更讲究的事。默认的3DGS训练迭代次数一般是30000步,学习率从1.6e-4开始做指数衰减。加入蒸馏信号后,我建议把基础重建loss的权重保持在1.0左右,蒸馏loss的权重从0.1起步慢慢往上加,最终不要超过0.5。
蒸馏权重的设定逻辑是:一开始让学生网络自己先摸索一个大概的结构,教师信号太强会把学生压得丧失灵活性;训练中段再逐步加大教师信号,帮助学生修正顽固伪影和时序抖动。这种做法类似课程学习,有效缓解了“学生完全复制教师错误”的风险。
高斯基元数量控制同样关键。3DGS训练过程中会周期性做densify操作,把梯度大的区域分裂或克隆出更多高斯。Lyra的蒸馏框架有个特点:教师模型给前景和背景的监督强度天然不一样,如果不对densify阈值做限制,很容易在前景边缘堆积大量高斯基元,导致显存爆炸。我的经验是把densify的梯度阈值从默认值调高一些,同时限制最大高斯数量为场景初始数量的3到5倍。
学习率方面,动态场景的变形网络学习率需要比主网络低一个量级。因为3D高斯的主坐标已经承担了静态结构的主要信息,如果变形网络更新太快,会把主坐标带偏,让整个模型抖动。推荐变量网络学习率设为1e-5到5e-5之间,配合早停策略在验证集PSNR不再提升时冻结。
3.4 评估指标与结果对比:怎么判断“SOTA”
静态场景的评估指标基本沿用PSNR、SSIM、LPIPS三个。PSNR衡量像素级误差,SSIM衡量结构相似度,LPIPS衡量感知相似度。英伟达在公开的benchmark上宣称新SOTA,一般是在这些指标上都有提升,尤其是LPIPS这类感知指标,因为蒸馏进来的教师先验天然擅长改善感知质量。
动态场景的评估更繁琐。除了逐帧算PSNR和SSIM,还要额外关注时序稳定性。比较常用的做法是算相邻帧渲染结果的差异图,如果某两个相邻帧之间差异异常大,说明时序上有闪烁。另外,对于动态场景,可以借助视频插值任务的表现来间接评估运动建模质量——如果中间帧插值准确,说明变形场学到的运动规律是合理的。
我自己在复现这类框架时有个习惯:不只盯着论文里的指标表格看,而是自己渲染一段连续视角的视频序列,肉眼观察有没有闪烁和漂移。量化指标再漂亮,渲染视频有明显闪烁,这个模型就没法上线用。Lyra的蒸馏框架对改善时序稳定性是有实际帮助的,但具体到某个场景,仍需要调节蒸馏loss的权重来找到适合自己数据的那组参数。
4. 实战排坑:这几类问题我建议你提前看
4.1 显存与算力:教师和学生同框怎么省
蒸馏框架最大的痛点不是效果,而是显存。学生端的3DGS光栅化已经吃显存,教师模型再往里一放,很多24G显存的卡直接不够用。我试过几种缓解办法,最有效的是对教师模型做梯度阻断,也就是教师只走前向推理,不求梯度,把推理得到的伪标签保存下来离线使用。
具体操作是:先用教师模型对训练数据做一轮完整的伪标签生成,存成npy或者png文件,然后在训练学生的阶段直接从磁盘加载这些伪标签。这样训练时的显存占用和学生单独训练几乎一样,唯一代价是磁盘IO和预处理时间。如果教师模型本身是视频级的(需要输入多帧),显存占用还会进一步增大,这时候可以分批处理——每8帧或16帧一个片段,生成伪标签后再拼接。
如果显存实在紧张,另一个技巧是降低光栅化渲染的分辨率做蒸馏loss计算。教师给出的伪标签分辨率即便低一些,结构信息也还有保留;学生主loss仍用原分辨率,蒸馏loss用降采样后的分辨率,整个训练过程的质量下降非常小。
4.2 蒸馏信号失效与伪标签过拟合
蒸馏不是加了就一定有效。我踩过的一个典型场景是:在某种特定纹理环境下,教师模型对某个区域的预测本身就是错的,学生不加分辨地学过去,反而把原来还算正确的结果带崩了。这就需要给蒸馏信号设定置信度阈值——教师模型在某个区域的预测置信度低时,强制这一块蒸馏loss置零,让学生回归基础重建loss约束。
怎么判断教师的置信度?简单一点的做法是用教师模型内部的概率输出做熵计算,熵高就是不确定;复杂一点的做法是教师模型同时输出一个uncertainty map,直接作为蒸馏loss的逐像素权重。Lyra这类框架在论文里常常会提到鲁棒蒸馏策略,现实中落地时这个置信度加权确实能挡住不少伪标签噪声。
另一个问题是伪标签过拟合。如果蒸馏loss权重太大,学生模型会快速贴近教师模型,失去自己从真实观测中挖掘细节信息的能力。表现出症状是训练几步PSNR就上去了但随后迅速下跌,或者渲染结果有一种“雾感”。遇到这种情况,优先降低蒸馏loss权重,其次考虑对教师伪标签做随机遮挡增强,让学生不能完全依赖教师输出。
4.3 动态场景下的时序一致性抖动
动态训练时,最让人头疼的是模型在少数几帧上收敛得特别好,中间某些帧却严重劣化——典型的时序不一致。排查思路其实不复杂。
先检查数据本身是不是有抖动:原始视频如果存在相机曝光不一致或者轻微的帧间偏移,那不管什么模型都救不回来。数据做一次全局的曝光校正和帧间对齐后,再跑训练对比一下,大概率能解决相当一部分问题。
如果数据没问题,那问题大概率出在变形网络和蒸馏时序信号之间的配合上。变形网络在时间维上通常用的是正弦位置编码,如果时间编码频率设置得太高,模型会对个别时间帧过拟合,导致帧间突变。可以尝试降低时间编码的最大频率,或者增加相邻帧运动向量的平滑正则项。
还有一个小技巧,动态训练时特意在训练集里留下几个固定时间戳做验证帧,每训练一定步数就渲染一次这几个帧,观察它们的PSNR变化趋势。如果验证帧的PSNR波动幅度超过1dB,基本说明时序训练不稳定,需要回调学习率或者调大运动平滑正则的权重。
4.4 常见问题速查表
| 问题现象 | 可能原因 | 处理办法 |
|---|---|---|
| 训练初期Loss不下降 | 学习率过大或COLMAP初始点云太稀疏 | 降低学习率到默认值一半;增加初始化点密度 |
| 场景中出现透明雾状伪影 | 高斯基元过度分裂且不透明度饱和 | 调高densify梯度阈值;限制最大高斯数量 |
| 动态场景帧间闪烁 | 时间编码频率过高或运动平滑正则过弱 | 降低时间编码高频;增大运动平滑权重 |
| 蒸馏loss很快降低但PSNR下滑 | 教师伪标签过拟合 | 降低蒸馏loss权重;加伪标签随机遮挡 |
| 显存OOM | 教师推理和学生训练同时进行 | 教师离线生成伪标签;训练时关闭教师梯度 |
| 渲染结果颜色偏灰 | 球谐系数被蒸馏loss过度约束 | 降低外观支路蒸馏权重;提高渲染域L2权重 |
| 变形网络把静态区域也带偏 | 变形网络学习率过高 | 降低变形网络学习率;增加静态区域mask |
这个表里的内容大部分是我在跑3DGS、动态3DGS和部分蒸馏模型时积累的经验,放到Lyra这个框架上同样适用。不同框架的底层机制再变化,这类问题在工程层面总是相似的。
5. 一点个人体会和扩展想法
Lyra最让我觉得有意思的地方,不是它用了多复杂的网络结构,而是它对“蒸馏”这个概念的重定义。过去蒸馏几乎等同于压缩,但在重建这个领域里,蒸馏真正解决的是“局部观测不足”和“时序信息割裂”这两个老问题。教师模型像一个全局视角的领航员,学生3DGS像一个实时响应的执行者,两者配合恰好能在保真度和实时性之间找到平衡点。
如果你准备在自己的项目里尝试Lyra,我的建议是先别急着上大场景、大数据集。挑一个静态小场景加上一个单物体动态场景,分别把蒸馏权重跑通,观察伪标签质量和训练稳定性。等两个场景都稳定了,再去挑战混合场景和长视频,效率会高很多。另外,可以多留意后续开源仓库里是否提供了蒸馏教师模型的checkpoint——如果有,直接用官方权重比你自己现训一个教师要省太多事。场景重建这个方向的迭代速度比大多数人想象的快,Lyra这套“先验蒸馏+3DGS”的范式,后续很可能还会延伸出更多的变体,值得持续跟进。