Gaussian Splatting has emerged as a high-performance technique for novel view synthesis, enabling real-time rendering and high-quality reconstruction of small scenes. However, scaling to larger environments has so far relied on partitioning the scene into chunks -- a strategy that introduces artifacts at chunk boundaries, complicates training across varying scales, and is poorly suited to unstructured scenarios such as city-scale flyovers combined with street-level views. Moreover, rendering remains fundamentally limited by GPU memory, as all visible chunks must reside in VRAM simultaneously. We introduce A LoD of Gaussians, a framework for training and rendering ultra-large-scale Gaussian scenes on a single consumer-grade GPU -- without partitioning. Our method stores the full scene out-of-core (e.g., in CPU memory) and trains a Level-of-Detail (LoD) representation directly, dynamically streaming only the relevant Gaussians. A hybrid data structure combining Gaussian hierarchies with Sequential Point Trees enables efficient, view-dependent LoD selection, while a lightweight caching and view scheduling system exploits temporal coherence to support real-time streaming and rendering. Together, these innovations enable seamless multi-scale reconstruction and interactive visualization of complex scenes -- from broad aerial views to fine-grained ground-level details.
- 城市场景撞上的第一堵墙是显存,以及原文给的那笔「每个高斯约 800 字节」的账。
- 前人两条路(切块/外存无 LoD)各自付出了什么代价。
- 三个预备式子:3DGS 的渲染式、H-3DGS 的层级与距离切。
- 全篇做法一句话:属性留在 CPU、结构放 GPU、大子树压成 SPT。
- SPT 的切法为什么更省更快,以及它换来的限制与
M_d保守距离。 - 并行切法依赖的那条堆条件,以及它为什么会在训练中被破坏。
- 训练中怎么让层级长大:spawn 与 respawn。
- 更准的最小距离度量(表面积)与视锥剔除、以及「什么时候重建」。
- GPU 缓存与视点调度:按 SPT 整块缓存、按距离比容差命中。
- 内存布局:哪些结构常驻显存、哪些随帧进出。
- 主结果:画质、显存、帧率三条线,以及
OOM那几格说明了什么。 - 消融与附录里的数据集、评测细节。
- 表 8 那张 √/× 特征对照表读到的是什么。
- 边界与反例。
1城市场景撞上的那堵墙:显存
先把这笔账算出来,因为后面所有设计都在回答它。 3DGS 的成本不在网络参数上,而在高斯本身:每个高斯要存均值、旋转、尺度、不透明度、球谐系数,训练时还要加一份优化器状态,前向与反向之间又会有排序与梯度累积的临时分配。原文把这四项加总后给了一个工程上限:实测大约每个高斯 800 字节[§3「3DGS Memory」, p2]。
这个数一乘就出事了。 按 800 字节算,1 GB 显存大约只放得下 50 万个高斯(1 GB ÷ 800 B ≈ 134 万…… 原文给的是约 50 万,因为它算的是在运行时同时驻留的那一部分,还要给渲染与反向留出余量)[§3, p2]。原文对这个后果的判词是:这严格限制了重建的细节量与场景范围[§3, p2]。
城市场景要多少个高斯? 本篇的实测数字可以直接回答:MC-small-city+ 上 Ours 用了 1.367 亿个高斯(表 1 的 #Gaussians 列)[表 1, p5]。这个量放在 24GB 的卡上,「全部驻留」这件事根本无从谈起,这正是下一篇要讲的那几格 OOM 的来由。
于是缺口被压成一句话:不是画质不够,也不是速度不够,是「这台机器装不下这个场景」。 原文在引言里把三条前人路线各自的代价摆开,其中两条是本篇要绕开的:
- 切块(partitioning):把场景分成若干块分别训练再合并。原文对它给的三条代价是:块边界处引入伪影、跨不同尺度训练变得复杂、对「城市级航拍 + 街景」这种非结构化场景适配很差[§1, p0]。
- 只靠外存、不管 LoD:数据放到 CPU 内存可以扩规模,但训练期省不下多少内存,原文的判词是「只能靠视锥剔除」[§2, p2]。少了一个维度:外存解决「放得下」,LoD 才解决「搬得动」。本篇要的是两件事一起做。
第三条前人路线是渲染侧的 LoD 压缩(属性量化、剪枝、按基元降球谐阶数,以及 Scaffold-GS、Octree-GS、Virtualized 3D Gaussians 那一支)[§2, p2]。它们主要面向内存受限设备或移动端,与本篇「单张消费级卡上训出城市规模」不是同一个问题的同一端。
1.1 本篇的立意:不切块
原文把「不切块」写进了第一条贡献里,而且给了一个「第一」的自评:这是第一个让 3DGS 能从任意视角、在不做空间分区的前提下,用外存与视角相关的流式加载在单张消费级 GPU 上训练并交互式渲染城市规模场景的框架[§1「Contributions」, p1]。
这句话要读准:重点不在「别人没做过多级」,而在前人把「按硬件挑档」当设计目标、把「不切块」当不必要。 切块在工程上是最省事的分治手段,但它把「接缝」变成了表示本身的一部分,而本篇要证明的是:接缝不是规模的必要代价。
这张图是这个系列的常客,但本篇与篇目 58 的用意相反。 FLoD 那张 teaser 让「同一份模型在两台机器上跑」并排出现,题眼是适配硬件;本篇这张题眼是一个场景本身太大。读的时候别把两者混成同一件事:一个是「资产按硬件分档」,一个是「资产按视角流式搬运」。
1.2 五条贡献
原文把贡献列成五条[§1, p1],后面每一章都会落到其中一条:
| # | 贡献 | 落在哪几章 |
|---|---|---|
| 1 | 不切块的城市场景训练与交互渲染:外存 + 视角相关流式,单张消费级卡 | 第 4、9、10 章 |
| 2 | 训练中的动态 LoD 层级致密化:层级在优化过程中持续演化,不需要训练后再建层级 | 第 7 章 |
| 3 | 面向高斯泼溅的分层 SPT(HSPT):混合数据结构,切法可并行、且对训练中的层级更新鲁棒 | 第 5、6 章 |
| 4 | 外存执行:缓存感知的流式与视点调度,靠时间相关性压低 CPU–GPU 搬运 | 第 9 章 |
| 5 | 大规模评测与新基准:提出 Uni10k 数据集、扩充分 MatrixCity Small City | 第 11、12 章 |
五条里有两条是「新数据结构」和「新数据集」,这在 3DGS 一系的论文里不算常见。 值得留意的是第 3 条里那个词:鲁棒(robust):它的落点不在「快」,而在「层级被训练改动之后,切法依然给出合法的切集」。第 6 章会说明前人切法为什么会在这件事上翻车。
2前人两条路的代价
这一章替读者把两条被人反复走的路拆开看,目的是让第 4 章「外存 + HSPT + 缓存」这套组合看起来不是凭空的。原文的相关工作里,与本篇直接相关的两条线是大规模重建与LoD 渲染[§2, p1–p2]。
2.1 分块路线:它买到了规模,付出的是接缝
分块这条线上站着本篇几乎所有的直接对标对象。 原文逐个点了名,而它们的分块方式各不相同,这本身就说明「怎么切」是个真问题:
| 方法 | 分块 / 层级方式 | 出处 |
|---|---|---|
| H-3DGS | 各块独立训练,再把它们合并成一份全局 LoD 层级 | [Kerbl et al. 2024][§2, p1] |
| CityGaussian | 分块训练 + 每块内部用 LightGaussian 做 LoD 选择 | [Liu et al. 2024a][§2, p1] |
| OccluGaussian | 分区时尽量让每块内相机的相关性最大 | [Liu et al. 2025][§2, p1] |
| VastGaussian | 解耦外观建模 + 渐进式分区 | [Lin et al. 2024][§2, p2] |
| Horizon-GS | 把分治与 LoD 机制整合起来,专攻航拍/街景混合数据 | [Jiang et al. 2025][§2, p1] |
| GrendelGS | 不做空间切块,改成把训练图像分到多张 GPU 上,每张设备渲一块不重叠的屏幕区域 | [Zhao et al. 2024][§2, p2] |
看这张表要抓两件事。 第一,除了 GrendelGS,其余全是空间切块;第二,Horizon-GS 恰好是「航拍 + 街景」这个场景的直接对手,而本篇的自评里那个「对非结构化场景适配很差」指的正是这类数据[§1, p0]。这说明本篇选了一个已经被切块路线耕耘过、但没被解决干净的战场。
另一条相关支线是从大规模场景里抽几何代理(TSDF 融合 + 几何损失生成多份网格,再用传统光栅化融合渲染)[Chen et al. 2025; Li et al. 2025; Liu et al. 2024b][§2, p2]。它与本篇不是同一类表示,原文只作对照列出。
2.2 「只靠外存」那条支线缺了一个维度
这一条最容易被忽略,但它正是本篇的第二个直接前身。 原文写:另有一些做法利用外存来扩训练规模,但没有考虑 LoD,于是训练期的内存下降只能靠视锥剔除[§2, p2]。
这句话的份量在于它把「外存」与「LoD」划成了两件事。 外存解决的是容量:数据不必全在显存里;LoD 解决的是搬运量:每一帧只搬当前视角真正需要的那一层细节。只做前者,搬运量与数据总量同阶:场景一大,CPU–GPU 的带宽就成了新瓶颈。第 9 章的缓存与视点调度,正是为这条缺口准备的。
2.3 LoD 渲染那条线:压缩为主,且多在「小设备」这一端
渲染侧的 LoD 在 3DGS 里主要朝两个方向走[§2, p2]:压缩类(用码本做属性量化、剪掉低影响的高斯、按基元降低球谐阶数;以及 Scaffold-GS 用锚定在参考高斯上的隐向量 + 运行时 MLP 生成关联高斯;Octree-GS 用空间细分把它扩到层级 LoD;Virtualized 3D Gaussians 借 Unreal Engine 5 的 Nanite 思路做组合场景)[Fan et al. 2024; Fang and Wang 2024; Huang et al. 2025; Niedermayr et al. 2024; Niemeyer et al. 2025; Papantonakis et al. 2024; Seo et al. 2024; Lu et al. 2024; Ren et al. 2024; Yang et al. 2025]。
原文对这条线没有给负面判词,只是划了位置,它们的目标是内存受限设备或移动端上的高效渲染[§2, p2]。这句话在定位上是自洽的:压缩类方法把「一份表示压到更小」,而本篇要的是「一份大到根本放不进去的表示,按需搬」。两者不冲突,但也替换不了。
第 12 章的表 8 会把这条路线的六个代表摆在一张特征表上,届时能看到本篇在「LoD 训练 / LoD 渲染 / 外存训练 / 交互渲染 / 无伪影 / 无分块」这六项上的位置,而这张表也是全篇唯一一张「自己给自己打分」的表,读法要特别交代。
把图 6 与图 7 并排读,就是第 1 章那句「不切块」的全部依据。 两张图在同一页、都印在参考文献续页之间,这是原文把一个论断加它的反证放在同一处的做法。
3三个预备式子与「每个高斯约 800 字节」这笔账
这一章把后面要用到的三个已知式摆好,并把第 1 章那笔账算实。 原文对 §3 的定位是「简要介绍与后续核定义最相关的关键项」[§3, p2]。
3.1 式 (1):渲染式
3DGS 用一组空间分布的高斯建模辐射场,每个高斯有均值 μᵢ ∈ R³、基础色 bᵢ ∈ R³、以及协方差 Σᵢ = Rᵢ Sᵢ Sᵢᵀ Rᵢᵀ(由对角缩放矩阵 Sᵢ = diag(s¹ᵢ, s²ᵢ, s³ᵢ) 与正交旋转矩阵 Rᵢ 参数化),另有不透明度 σᵢ 与用球谐系数 fᵢᵈ 表达的视角相关颜色(球谐阶数 d 决定表达力,每个高斯需 Σⱼ₌₁ᵈ 3·(2j+1) 个参数)[§3, p2]。
渲染时,全部 N 个高斯按到相机的距离排序,然后对每个像素 x(对应视线方向 v)求体渲染方程的离散近似:
其中 αⱼ 是视线方向上第 j 个高斯的不透明度:
这里 μ′ 与 Σ′ 是投影到图像平面后的 2D 均值与协方差,由投影变换的仿射近似得到[Zwicker et al. 2001][§3, p2]。
这两条式子本身没有新东西,但有一处要划下来:式 (1) 里那个 Π 是「前面的高斯一个都不能漏」的意思。 对大规模场景而言,这意味着每一帧都必须把沿途所有该画的高斯凑齐:第 4 章的流式加载与第 9 章的缓存,都是为了让这个「凑齐」不撞上显存墙。
3.2 式 (3):层级与距离切
H-3DGS 引入的做法是把邻近高斯递归合并成一棵树:每个非叶节点近似它的孩子,叶节点就是原始高斯[§3, p2]。所谓切割(cut)由一条条件 c_hier(i, cam) 在广度优先搜索(BFS)中求值:若某节点满足条件,它就进切集、跳过其孩子;否则继续 BFS。一个合法切集里不含任何被选节点的父或子,因而给出一份视角自适应的 LoD 表示[§3, p2]。
距离切的具体形式(H-3DGS 用的)是[§3, p2]:
同一式里 md(i) 的定义是 md(i) = |μᵢ − p_cam| … / maxⱼ sʲᵢ,也就是把「节点到相机的距离」除以「该节点的最大尺度」。
原文对式中符号的说明是:p_cam 是相机位置,T 是全局 LoD 阈值,md(i) 是「观察高斯 i 可接受的最小距离」;而 BFS 保证:若 i 在切集里,则它的父必然没通过条件,即 md(parent(i)) > … ≥ md(i)[§3, p2]。
T、c_hier(i, cam) =、2 ≥ m_d(i)、m_d(i) =、μᵢ − p_cam、maxⱼ sʲᵢ 各占一行)。站内按同一含义的线性写法整理并注明,不替原文补式子。这条条件里已经埋着第 6 章的引线。 注意最后那半句:「若 i 在切集里,则父必然没通过条件」。这是一条关于父子关系的约束:它默认「父比子更粗」。第 6 章会说明,训练中一改层级,这条默认就可能不成立。
3.3 这笔账自己算一遍:800 字节与 50 万高斯
第 1 章那个数值得自己算,因为它决定了全篇的规模感。 原文给的分解是四项:逐高斯的属性(均值、旋转、尺度、不透明度、球谐系数)、优化器状态、以及前向/反向期间的临时分配(排序、梯度累积等);后一项随高斯尺度与剔除效率浮动,但工程上大致可按每个高斯 800 字节上界[§3, p2]。
| 口径 | 算式 | 结果 |
|---|---|---|
| 每高斯开销(工程上界) | 原文实测 | 约 800 B |
| 1 GB 显存能放多少 | 1 GB ÷ 800 B | ≈ 134 万个(纯算术) |
| 原文给的可用数 | 还要给渲染与反向留余量 | 约 50 万个 / GB |
| 本篇实测的最大场景 | MC-small-city+ 的 Ours | 1.367 亿个高斯(表 1) |
| 若全驻留需要多少显存 | 1.367 亿 × 800 B | ≈ 109 GB |
最后一行的 109 GB 是这一章最该记住的数。 它说明为什么切块路线会成为默认选择,也说明为什么本篇的非切块路线必须把「全部驻留」这件事整个拿掉:目标在于让「驻留」这件事不再发生,而非压低显存占用。
这张图与图 5-1 是一对,分读「结构」与「实测」:图 9 说清哪些东西在哪一层内存,图 5-1 给一次训练迭代的 CPU/GPU 峰值实测。第 10 章会把后者接上。
4全篇做法一句话:属性留在 CPU、结构放 GPU、大子树压成 SPT
第 1 章那笔 109 GB 的账,决定了这一章只能有一个答案:让「全部驻留」这件事不发生。 原文在 §4 开头的三句话,就是整套系统的骨架[§4, p2]。
4.1 骨架三句
第一句:高斯属性全部放到 CPU 内存,按训练视角、按 LoD 层级按需流到 GPU。 原文写:为了训练超出显存上限的模型,所有高斯属性都存放在 CPU RAM 里,并按照 LoD 层级、为每个训练视角按需流式送进 GPU[§4, p2]。这一句拿掉的是「驻留」。
第二句:显存里只留一份,而且只留树结构。 原文写:为了加速层级切割,我们只把树结构的一份副本存进 VRAM,其中较大的子树被 Sequential Point Trees(SPT)替换掉,形成分层的 SPT(HSPT)[§4, p2]。这一句拿掉的是「属性的副本」。注意「只」这个字:进显存的不是高斯,是树的骨架。
第三句:搬运要记账,不能盲搬。 原文写:为了把 RAM 与 VRAM 之间昂贵的传输压到最小,我们跟踪哪些 SPT 当前驻留在 GPU 内存里、以及处于什么细节层级;只有当一个 SPT 不在缓存里、或者层级差异不够近似时,才从 RAM 载入它[§4, p2]。这一句拿掉的是「重复搬运」。
三句合起来是一件事的三个面:容量(属性外存)、常驻(只留结构)、搬运(按块按需)。第 9 章会看到第三句的判据具体长什么样。
4.2 一次训练迭代走一遍
原文把训练与致密化的整体流程放在 Figure 8(8 步)与附录 A.7 的 Algorithm 3(Full train procedure)里[§4, p2;§A.7, p17–p18]。按原文 §4 的叙述,一次迭代可以拆成这样的链:
| 步 | 做什么 | 在哪一侧 |
|---|---|---|
| 1 | 对当前训练视角,在上层层级上做 BFS 切 | GPU(结构常驻) |
| 2 | 切出来的节点里,属于 SPT 的那些再按根距离切一次 | GPU |
| 3 | 需要的高斯从三个来源汇集:上层树本身、从 RAM 新载入的 SPT 切、缓存命中 | GPU + RAM |
| 4 | 光栅化、算损失、反向 | GPU |
| 5 | 优化器更新(属性在 CPU 侧维护) | CPU/GPU 协作 |
| 6 | 在 CPU 上做致密化:给节点长出新的叶、重挂死亡的叶 | CPU |
| 7 | 层级更新完,转回 HSPT 并传到 GPU | CPU → GPU |
| 8 | 进入下一轮迭代 | — |
这张表里有一步是全篇的地基:第 6 步在 CPU 上做。 原文的措辞是「致密化在 CPU 上执行,做法是给层级加入新的叶节点、并重新生成(respawn)低不透明度的叶节点;致密化之后,更新过的层级被转回 HSPT 并传到 GPU,进行新一轮训练迭代」[§4, p2]。第 7 章会把这一步的两个操作拆开讲。
为什么「层级在训练中被改」这件事值得单开一章? 因为它恰好是前人切法失效的地方:第 6 章会给出原文对这件事的完整论证。这里先记住:第 6、7 两章是连着的,一个说「层级会被改」,一个说「改完之后切法还站得住」。
4.3 分工表:谁放在哪一层
| 数据 | 存放位置 | 随帧变化 | 出处 |
|---|---|---|---|
| 高斯属性(均值/旋转/尺度/不透明度/球谐) | CPU RAM | 按需流入 VRAM | §4, p2 |
| 树的结构(含被压成 SPT 的子树) | VRAM(常驻) | 每次致密化后重建 | §4, p2 |
| SPT 的切(当前视角量出来的那一批) | VRAM 缓存 + RAM | 每帧可能变 | §4, p2;§4.4, p4 |
| 优化器状态 | 与属性同侧 | 每步 | §3, p2 |
这张表解释了第 3 章图 9-1 的那条分界线。 也解释了为什么本篇的显存占用与「场景里的高斯总数」解耦:常驻的是结构,属性只按需进出。
读这张图要盯住一处对照:第 3 步的三个来源里,「缓存命中」是唯一一个不产生 CPU–GPU 传输的来源。原文 §4.4 整节都在扩大这一项的比例,第 9 章讲它。
5SPT:更省、更快、也更受限的一种切法
这一章讲 HSPT 的两个组成部分里的第一个。 SPT 不是本篇发明的,它来自 Sequential Point Trees,原是给点云做 LoD 渲染用的,原文的判词是它可以平凡地(trivially)推广到椭球与高斯[§4.1, p2]。
5.1 式 (4):把切条件从「父到相机」换成「根到相机」
换掉的那一步很关键。 原文写:SPT 施加了一条比 Kerbl et al. [2024] 更受约束、但更高效的切条件[§4.1, p2]:
原文把同一件事写成 c_SPT(i, cam) = ( |μ_root − p_cam| … ≥ m_d(i) ),与上式等价,只是这里改成了区间形式。
式中唯一的新意是:距离那一项换成了「这个 SPT 的根节点到相机」,而不再用「父节点到相机」。 原文紧接着解释了这条替换买到了什么:这条条件可以对 SPT 里所有高斯并行求值,因为它们共用同一个「根—相机 距离」;而且它只需要存排序好的对 (md(i), md(parent(i))),于是内存占用显著低于完整的层级[§4.1, p2]。
把这两件事分开看,SPT 的账才清楚:
| 维度 | 换成「根距离」之后 |
|---|---|
| 并行性 | 所有高斯共用同一个距离量 ⇒ 求值可完全并行 |
| 内存 | 只需存 (md(i), md(parent(i))) 的有序对,不需存完整父子结构 |
| 正确性 | 原文声明:切法保证是合法的(不满足 md(parent(i)) > md(i) 的节点绝不会被选进切集)[§4.1, p2] |
5.2 排序加二分:截断点怎么找
有了「所有高斯共用一个距离量」这个性质,切割就退化成一次查找。 原文写:为了优化切割,高斯按 md(parent(i)) 降序排序;再用二分查找定出截断下标 N,下标大于 N 的高斯太细、不参与渲染[§4.1, p2]。
这一步是 SPT 之所以叫「Sequential」的原因:它把「走一遍树」换成了「在一个有序序列上二分」。对大规模场景,这意味着每帧的切割成本与树的深度无关,只与一次排序+一次二分有关。
5.3 代价:一个 SPT 里所有高斯的细节层,都由「到根的距离」决定
原文对这个限制写得很直白:一个 SPT 里所有高斯的细节层,显然都在由「相机到它根节点的距离」支配[§4.1, p3]。
这句话的后果具体是什么? 原文接着说:这可能导致某些高斯被渲染出来,尽管按当前视角它们已经太粗了,也就是说,md(i) > |μᵢ − p_cam|²/2 的高斯仍可能被选中[§4.1, p3]。
换句话说:一个 SPT 是「整包发货」,而包里的个体不一定都适合当前视角。 一个离相机很远的高斯、若它与根节点挤在一起,就会跟着根节点一起被当成远景处理,而它其实可能正对着镜头。
5.4 修补:把 md 换成保守的 Md
原文的修补是一步不动结构的数学改动。 它定义[§4.1, p3]:
Md(i) = md(i) + |μᵢ − p_cam|² / 2,把它当作一个保守的最小距离函数[§4.1, p3]
然后它用三角不等式给出保证:选出满足 Md(i) ≤ |μ_root − p_cam|²/2 的高斯,就保证了 md(i) ≤ |μᵢ − p_cam|²/2[§4.1, p3]。
把这句话翻译一下:把「根的距离」当作预算上限,再从里面扣掉「这个高斯离根有多远」这笔开销。 于是:「离相机比根节点更远的高斯,会被选在更高的细节层」[§4.1, p3]。这正是 5.3 节那个问题的反面:靠近根的高斯继续按根的距离处理,偏离根的个体则被单独加细。
| 量 | 含义 | 用途 |
|---|---|---|
| md(i) | 观察高斯 i 可接受的最小距离(式 (3) 定义) | 判「这个高斯够不够细」 |
| Md(i) | md(i) 加上「i 到相机的距离平方」的一半 | 在「只用根距离」的框架里保住个体正确性 |
5.5 它适合什么、不适合什么
原文给了 SPT 的适用条件:SPT 最适合那些紧密成团、且观察距离大于它们相互间距的高斯;它们的紧凑内存占用与可并行求值使它们很适合大规模场景[§4.1, p3]。
这句话反过来读就是限制:如果一「团」高斯散得很开,或者相机挤进了它们中间(观察距离小于间距),用根距离统一处理就会明显失真,这也解释了第 6 章为什么要把 SPT 只用在层级的下半截,而不是全程用它。
前提 1:这个 SPT 内所有高斯已按 m_d(parent(i)) 降序排好序。
前提 2:M_d(i) 已按式 (4) 的保守形式算好(含「i 到相机的距离」那一项)。
# == 每帧、每个 SPT ==
dj ← ‖μ_root − p_cam‖₂ # 整块共享的根距离
idx ← 在排序序列上二分,找满足 M_d(i) ≤ dj²/2 的最后一个下标 N
cut ← 序列的前 N 项 # 这批高斯进渲染
这段伪码对应原文附录 A.7 的 Algorithm 2(SPT Cut)[§A.7, p17]。内环里没有树遍历,只有一次二分,这是它比 BFS 便宜的全部原因。
Vertical lines show binary search results; horizontal lines show distance cuts)。(b) Densification example 画的是叶节点致密化与重挂。②读法:(a) 要横着比两种结构:同一批高斯、同一视角,两种结构切出来的集合形状不同;把「红线落在哪一层」与 5.2 节的二分、5.4 节的 Md 对上。(b) 见第 7 章。
来源:A LoD of Gaussians, Fig. 2, p3 · © 2026 the owner/author(s)(CC BY-NC-ND 4.0)· 原样引用,未修改
6HSPT:为什么要拼两种结构
第 5 章的 SPT 已经能切了,为什么还要再造一个 HSPT? 原文在这一节开头就交代了动机:先回顾前人的 LoD 选择做法,再说明为什么需要一个新数据结构[§4.3, p3]。答案分两半,一半关于并行,一半关于正确性。
6.1 BFS 切:正确,但难并行
最直白的解法是广度优先遍历。 原文写:从根做 BFS 能保证一个合法切集,并且可以提前剪掉大子树(例如靠视锥剔除);但它接着给出判词:图遍历很不适合在 GPU 上并行,因此在大规模下代价高得不可接受[§4.3, p3]。
于是有了第二步:把切条件改成逐高斯并行求值。
6.2 并行切(式 5)与它背后的那条前提
Kerbl et al. [2024] 的并行切法是逐高斯求值[§4.3, p3]:
原文对它的解释是:一个在当前相机距离下已经足够小、而它的父又大到无法渲染的高斯,应当进切集[§4.3, p3]。
紧接着是这一节最要紧的一句:这条做法只在「子高斯的 md 恒小于父高斯」这条假设成立时才给出合法切集,也就是堆条件:
这条条件什么时候成立? 原文说得很清楚:当层级是在训练结束之后才构造的时候,它一般是成立的,因为父高斯代表的是孩子的更粗近似[§4.3, p3]。
6.3 层级一动,堆条件就可能倒挂
接下来是全篇最关键的一段判词。 原文写:然而,当层级在训练与致密化过程中被修改时,优化可能破坏堆条件:导致不合法的切集,以及会随时间越变越坏的退化层级[§4.3, p3]。
把因果链拆开,这一段说的是三件事:
- 层级会被改(第 7 章的那两个操作:spawn 与 respawn);
- 一改就可能出现 md(i) ≥ md(parent(i)):即「子并不比父更细」;
- 于是并行切(式 5)给出的切集不再合法,而且因为层级是继续被优化的,退化会累积(原文用的是
worsen over time)。
这就是第 3.2 节埋下的引线被引爆的地方。 §3 描述 H-3DGS 的 BFS 时说过「若 i 在切集里,则其父必然没通过条件」[§3, p2]:那句话在训练后建层级的前提下是自然成立的,而在训练中改层级的前提下就不再自动成立。前人切法并没有写错,只是它的适用前提被换掉了。
6.4 HSPT 的构造:先用体积阈值把层级切成两半
HSPT 没有去修补式 (5),它把层级先分成两半,让两半各用各自站得住的方法。 原文写:为了从高斯层级构造 HSPT,我们用一个 BFS、按条件 c_HSPT(i),也就是三个尺度的乘积 s¹ᵢ·s²ᵢ·s³ᵢ 与阈值 size 的比较:来切它[§4.3, p3–p4]。
这个切集把层级分成两部分:上层层级(包含所有体积大于 size 的高斯)与下层层级(由切集里的节点为根的子树组成)[§4.3, p4]。
关键在于下层为什么可以安全地换成 SPT。 原文的推理链是:下层里每个根节点的体积现在被 size 界定,而这同时也粗略界定了该子树里所有高斯的范围;于是把子树转成 SPT 所引入的误差有了一条上界;因此,切集 C_HSPT 里每个足够大的子树都可以转成 SPT,而不会破坏更高层的切割正确性[§4.3, p4]。
这段话是本篇最精密的一处论证,值得停一下。 它把「误差上界」与「结构选择」挂上了钩:体积阈值 size 同时扮演两个角色,它是「切在哪里」的判据,也是「换成 SPT 之后最多错多少」的保证。SPT 在 5.5 节里被说成「适合紧密成团的高斯」,而 s¹s²s³ < size 恰好就是在圈的紧密度:体积小的子树才是紧密的,才适合整包处理。
6.5 两步切割
分完两半,切割就是两步[§4.3, p4]:
| 步 | 做什么 | 为什么这一步是对的 |
|---|---|---|
| 第一步 | 在上层层级上做 BFS,选出当前视角需要的节点与「叶/SPT 子树」 | BFS 保证合法切集,且能提前做视锥剔除 |
| 第二步 | 每个被选中的 SPT,按「相机到它根节点的距离」切 | SPT 自带的切法保证合法(5.1 节) |
这两步合起来,就是绕开堆条件的全部办法:上层用不依赖堆条件的 BFS,下层用自带正确性保证的 SPT 切法。没有任何一步依赖「子比父更细」这条假设,所以层级在训练中被怎么改,切出来的集合仍然合法。
A Gaussian hierarchy is converted to an HSPT by cutting according to...)。②读法:先找那条把层级分成上下两半的界线,它对应 6.4 节的体积阈值 size;再看上下两半各自被怎么处理(上半 BFS、下半 SPT)。这张图是唯一把「两半」画出来的图,正文文字只给了条件,形状要靠它。
来源:A LoD of Gaussians, Fig. 3, p3 · © 2026 the owner/author(s)(CC BY-NC-ND 4.0)· 原样引用,未修改
前提 1:高斯层级已建好,且每个节点能算出体积 s¹·s²·s³。
前提 2:size 是体积阈值,它同时决定「切在哪」与「换 SPT 的误差上界」。
# == 构造 HSPT(只在每次致密化之后做一次)==
用 BFS 按 c_HSPT(i) = (s¹ᵢ·s²ᵢ·s³ᵢ < size) 切层级
→ 切成「上层层级」(体积 > size)与「下层子树集合」
把下层里每个足够大的子树替换为 SPT
# == 每帧、每视角切割 ==
第一步:在上层层级上 BFS,选出节点与「叶/SPT 子树」,逐节点做视锥剔除
第二步:对每个被选中的 SPT,按 ‖μ_root − p_cam‖₂ 切(第 5 章的二分)
这段伪码对应原文附录 A.7 的 Algorithm 1(BFS Hierarchy Cut)[§A.7, p17]。
第 6 章的结论可以用一句话收:HSPT 不是「把两种结构拼起来」这么简单,它是把「谁依赖哪条前提」分清楚的产物:BFS 不依赖堆条件所以放在上层,SPT 自带正确性所以放在下层。第 7 章接着说:层级在训练中到底被改成了什么样。
7训练中让层级长大:spawn 与 respawn
这一章是第 6 章的前提。 6.3 节说「层级一动,堆条件就可能倒挂」:那么层级为什么要动?原文在 §4.2 开头就点明这件事的难处:致密化一个 LoD 表示带来一个特别的挑战,因为层级结构必须在训练过程中持续演化[§4.2, p3]。
7.1 前人怎么绕开这个问题
原文先说了前人的处置:前人工作绕开这个问题的办法是:只在块级训练与致密化完成之后,才去构造 LoD 层级[§4.2, p3]。
这句话把「不切块」与「训练中致密化」之间的关联讲清了。 前人是「先分块训完、再建层级」,所以层级在建好之后就不再改,堆条件自然成立;而本篇既不分块、又要训出层级,就必须在建好的层级上继续改动,于是问题被推到面前,绕不过去。
7.2 spawn:借「split」的形,改「split」的义
原文的灵感来源是 3DGS-MCMC:它「分裂(split)」高斯:用一个新高斯替换成两个,而这两个合起来应当看起来与原来相似[§4.2, p3]。
接着是原文一个很漂亮的观察:这一步恰好与「高斯层级里父节点近似它的孩子」是同一件事[§4.2, p3]。
于是处置就顺理成章了:原文说,受这个对应关系启发,我们采用同样的做法,但是为高斯「生育(spawn)」两个新的子节点,从而以最小的伪影代价增大层级[§4.2, p3]。
这一改动的效果原文也给了:它带来致密化过程中细节的渐进增长,从而避开了在 [Kerbl et al. 2024] 里观察到大场景上的那种不稳定[§4.2, p3]。
| 3DGS-MCMC 的 split | 本篇的 spawn | |
|---|---|---|
| 动作 | 一个高斯 → 两个高斯 | 一个高斯 → 两个子节点 |
| 结构含义 | 平面的:两个新基元 | 层级的:父近似两个子,与层级语义自洽 |
| 结果 | 基元数增加 | 层级规模增大,且细节渐进增长 |
7.3 respawn:不剪枝,改重挂
3DGS 一系处理「不再需要的高斯」惯常是剪掉,本篇走的是另一条。 原文先交代 3DGS-MCMC 的做法:它不剪枝,而是把不透明度低于阈值的高斯判为「死亡」,并把它们在某个高不透明度高斯的位置上重新生成[§4.2, p3]。
本篇提了一条相似的策略,但必须适配层级:
- 当一个叶节点死亡时,它的父节点被它的兄弟节点顶替;
- 死掉的叶节点与它原来的父节点,随后被重新挂到另一个节点下面作为孩子,而那个节点是被选中要致密化的[§4.2, p3]。
这段操作要顺着树来看才不绕。 一个叶死了,父节点少了一个孩子;如果父只有一个孩子了,那父就成了多余的一层,所以让兄弟顶替父,把这一层抹平;被抹掉的那两个节点(死叶与旧父)不浪费,而是搬到另一个正在长大的节点下面去当孩子。原文对这个过程的总结是:这两个操作合起来,保证层级在训练中能够以稳定且合法的方式扩张,并在需要时被重新配平[§4.2, p3]。
「重新配平(rebalanced)」这个词值得记下。 剪枝会让树失衡,而重挂把节点搬到正在生长的分支上,这是一个再平衡而不是删除的动作。对第 6 章而言,这一点很重要:树被改得越频繁,堆条件被破坏的机会越多,所以每次改动都必须同时维持「合法」。
7.4 选谁去致密化:不透明度加权随机,还是屏幕空间梯度
原文在两处候选策略之间做了选择,而选择的理由比选择本身更值得看。 它写:3DGS-MCMC 用「按不透明度加权的随机选择」来挑要致密化的高斯,而我们采用 [Kerbl et al. 2024] 的策略:按最大屏幕空间梯度来挑[§4.2, p3]。
给出的理由是:这个判据让致密化更贴合大规模场景里的视角相关重建误差[§4.2, p3]。
换句话说:不透明度是个「这个高斯有多重要」的标量,而屏幕空间梯度是个「这个位置在当前视角下差多少」的判据。 大规模场景里不同视角看到的东西差得很远,前者会错过「重要但当前视角渲得还行」与「不重要但当前视角渲得很差」这两类,后者直接盯误差。细节见附录 A.6[§4.2, p3]。
致密化这两个操作合起来,正是第 6 章「层级会被改」的具体内容。 到这里,「为什么需要 HSPT」这件事就完整了:原因并不在「我们想改层级」,而在:不切块 + 训练中致密化这条路,必然要改层级。
8更准的最小距离、视锥剔除与重建时机
第 5–7 章把结构讲完了,这一章讲三处「什么时候做、用什么量做」的工程判断。 它们看起来是细节,但原文在 §4.3 里给了完整理由。
8.1 什么时候重建 HSPT:只在致密化之后
先看一个明显的取舍。 原文写:每个训练迭代都重建 HSPT 会把它的性能收益抹掉;所以它换了个思路:利用「最小距离 md 在优化过程中演化得很慢、因此只需要不频繁地更新」这个事实;实践中的做法是:只在每一次致密化步之后重建 HSPT[§4.3, p4]。
这条判断把「重建成本」与「层级变动」对齐了:层级只在致密化时变(第 7 章),那重建也跟着致密化走,中间那些迭代就白拿收益。
8.2 式 (6):用表面积而不是最大尺度
「不频繁重建」还买到了第二件事:既然重建不贵,那就可以用一个更准但更贵的度量。原文写:这种不频繁的重算,允许我们使用一个比「最大尺度的倒数」更准(虽然更贵)的最小距离度量[§4.3, p4],具体定义为:
原文对这个量的解释是:它对应高斯椭球表面积的开方倒数(相差一个常数因子)[§4.3, p4]。
它比旧度量好在哪,原文也写明了:它更好地抓住了各向异性高斯的「视觉大小」,尤其是那些在一个或多个方向上明显被拉长的高斯[§4.3, p4]。
| 度量 | 形式 | 对细长高斯的表现 |
|---|---|---|
| 旧:最大尺度的倒数 | ∝ 1 / max(s¹, s², s³) | 只看最长的一根轴 ⇒ 细长高斯被当成「很大」 |
| 新:式 (6) | ∝ 1 / √(s¹s² + s¹s³ + s²s³) | 三项乘积和 ⇒ 把「扁平」也算进去,更接近视觉大小 |
这一处替换在城市场景里不是小事:航拍看到的地面片、建筑立面的薄片,都是典型的细长/扁平高斯。用旧度量会把它们误判为需要高细节,白白多载数据。
8.3 视锥剔除:给子树一个球,早一步剪掉
BFS 切上层的另一个好处是能提前剪。 原文写:用 BFS 切上层层级的主要收益,是既保证切集合法、又能提前剪掉子树;因此它对 BFS 里考察的每个节点都做视锥剔除:做法是检查一个围绕高斯、半径为 3·maxⱼ sʲᵢ 的球是否与视锥相交[§4.3, p4]。
原文对这处近似做了诚实的交代:拿高斯尺度当整个子树范围的一个保守代理并不完全准确,但在实验里与「完整包围球层级」相比没有观察到可辨差异[§4.3, p4]。
接着它交代了这处早剔除为什么值得:虽然高斯在光栅化阶段本来就会被隐式剔除,但这个提前剔除加速了切计算,并且显著减少了从 RAM 载入的高斯数[§4.3, p4]。
这句话把第 4 章那三句骨架又串了一遍:早剔除省的不只是算力,主要是搬运,而在「属性在 CPU」的架构里,搬运就是主要成本。证据是图 10-1。
Frustum Culling and LoD selection (left) greatly reduces the...),所以左边那部分是「做了」,右边(或对照组)是「没做」。②读法:看的是「从 RAM 载入的高斯数」这个量,不是画面质量,这张图的论点是省搬运,不是省算力。把它与 8.3 节那句「显著减少从 RAM 载入的高斯数」对上。
来源:A LoD of Gaussians, Fig. 10, p9 · © 2026 the owner/author(s)(CC BY-NC-ND 4.0)· 原样引用,未修改
这一章的三处判断有一个共同点:它们都把「不常做」与「做一次就要做得准」配成一对。 重建不常做 ⇒ 度量可以用贵的;剔除每帧做 ⇒ 代理可以用粗的(因为便宜且实测无差)。这种「按频率配精度」的分工,是本篇工程判断的底色。
9GPU 缓存与视点调度:按整块 SPT 缓存、按距离比命中
第 8 章的两次「少搬」都还停在「这一帧要不要搬」。这一章解决的是跨帧的问题:同一批高斯在连续几帧里都在用,凭什么每帧都从 RAM 再搬一遍?
先把成本说准。 原文写:从 RAM 载入高斯数据是一件昂贵的操作,在大规模训练里会变成显著瓶颈[§4.4, p4]。这是全篇的第二个成本前提(第一个是第 3 章那笔显存账):显存不够 ⇒ 只能外存;外存 ⇒ 搬运本身就成了新的墙。
9.1 缓存的是「整块 SPT 切」,不是单个高斯
最直白的做法是逐个高斯判断命中,原文把它否掉了:那样会引入不小的开销[§4.4, p4]。理由可以自己推:城市规模是上亿高斯,逐件查一遍,光判断的代价就够把省下的搬运吃回去。
SPT 在这里又当了一次解药。 原文写:我们再一次用 SPT 换了个高效的做法:不去缓存单个高斯,而是把「SPT 切」里的高斯、连同「相机到该 SPT 根的距离」一起存下来,后者记作 d̄ⱼ(第 j 个 SPT)[§4.4, p4]。
喻体回扣(第 5 章立桩):SPT 是整包发货。缓存顺着同一个粒度走:一包一包地存、一包一包地查,不做逐件清点。「粒度跟着结构走」是这一章的第一处判断:数据结构换了,连缓冲策略也得跟着换,否则省下的东西会被查找开销吃掉。
9.2 式 (7):一个双端的距离比
命中判断用两个距离:缓存里存的那个 d̄ⱼ,与当前帧现算的 dⱼ = ‖μ_root(j) − p_cam‖₂[§4.4, p4]。条件是:
两端各管一件事,原文说得极清楚:D_max 界定「允许用比最优更粗的细节」的范围,D_min 限制「能容忍多少比最优更细的细节」[§4.4, p4]。
| 参数 | 管的方向 | 直白的读法 |
|---|---|---|
D_max | 上界 | 相机退远了、本该载更粗的档;只要没远过头,就继续用缓存里这份偏细的 |
D_min | 下界 | 相机凑近了、本该载更细的档;只要没近过头,就继续用缓存里这份偏粗的 |
dⱼ / d̄ⱼ | 比值 | 两端都不越界 ⇒ 复用缓存里这一整包,省掉一次 RAM→GPU 搬运 |
这一处设计里有一句反直觉的话,必须单独点出来。 原文说:这个启发式会引入轻微的渲染细节波动(因为 LoD 取决于缓存状态),但我们发现这种随机性其实提升了训练的鲁棒性:跨视角的细节上的细微变化,抑制了对固定相机距离的过拟合,促进了跨尺度的泛化[§4.4, p4]。
一般工程直觉是「命中率越高越好、细节越稳越好」,原文讲的正好相反。 因为判断带容差,同一处几何在不同帧可能落到不同档;这个「不确定」本身成了正则化项。它和第 7 章那处「不透明度加权随机 vs 屏幕空间梯度」是同源的手法:先在某个环节引进一点随机,再让这点随机去做防过拟合的活。
9.3 一帧里的高斯从哪来:三处汇集
这是图 4-1 的读法,必须逐来源对着看。 原文写:每个训练视角,可见高斯由三处汇集:上层层级、从 RAM 新载入的 SPT 切、以及缓存命中;优化之后,新访问的 SPT 被加进 GPU 缓存[Fig. 4 图注, p4;§4.4, p4]。
Gaussians required for the current training view are assembled from three sources: the upper tree, newly loaded SPT cuts from RAM, and cache hits.]。②读法:跟着箭头走一遍「RAM → 缓存 → 渲染集」这条路,重点看哪些框标了 RAM、哪些框在 VRAM 里:第 10 章的驻留策略表就是把这张图翻成文字。
来源:A LoD of Gaussians, Fig. 4, p4 · © 2026 the owner/author(s)(CC BY-NC-ND 4.0)· 原样引用,未修改
显存要有上界,原文用的是 LRU 写回:超过内存阈值时,条目被写回 RAM;另外,为了不让模型过拟合到那些长期驻留的缓存条目上,整个缓存每 1000 次迭代被清空一次[§4.4, p4]。
「每 1000 次迭代清空一次」是个容易被跳过的设定,但它和 9.2 节那句是同一件事的两面:容差带来逐帧的小扰动,清空带来周期性的大扰动。两者都在防同一件事:模型只学会在「它恰好有钱搬进来的那批高斯」上把画面做好。
9.4 视点调度:先让相邻两帧用得上同一批货
缓存要有效,前提是连续两帧确实共用高斯。 原文先承认这个前提有多难满足:在大规模场景里,GPU 缓存通常只覆盖整体几何的一小部分,导致命中稀疏;为了提高缓存利用率,我们按空间局部性挑选后继训练视角:选离当前视角近的,最大化高斯复用[§4.4, p4]。
做法是一张 k 近邻图加一个采样分布。 原文写:为此我们预计算所有训练视角位置上的 k 近邻图,边权 w_ij 是视角 i 与 j 之间的欧氏距离;下一个训练视角 j 就从当前视角 i 的 k 个近邻里按分布 P(j|i) ∝ 1/(w_ij + W) 采样,其中 W 是归一化常数,同时也控制探索的程度[§4.4, p4]。
| 符号 | 含义 | 作用 |
|---|---|---|
w_ij | 视角 i、j 位置之间的欧氏距离 | 距离项:越近权重越大 |
W | 归一化常数 | 同时控制探索程度:W 越大,分布越平,越不挑近的 |
这里有一个必须防的副作用,原文自己先说了:偏离均匀采样的训练视角选择要小心,因为它可能引入偏置;为此,我们每 128 次迭代注入一个随机选出的视角,实测足以保住泛化性能[§4.4, p4]。
「每 128 步注入一个随机视角」与「每 1000 步清空缓存」是同一种手法的两个尺度:一个防「视角分布太集中」,一个防「高斯驻留太集中」。全篇反复出现同一个句式:先用一个机制换性能,再补一个便宜的随机化把它的副作用按住。 这一条在读完第 12 章的消融表之后会更清楚:那些「随机性」都没有换来画质提升,它们买的是鲁棒性。
这一章还欠一笔账:究竟省了多少。 表 4 的读数是从 RAM 载入的高斯数由 162.9 万降到 29.1 万、再降到 8.9 万;表 3 的读数是关掉缓存会把 MC-small-city+ 的渲染帧时间从 68.3 ms 拉到 127.4 ms[表 3、4, p6/p11]。这两张表在第 12 章逐格算。
10内存布局:哪些常驻显存、哪些随帧进出
第 3 章算的是「每个高斯要多少字节」,这一章看的是「这些字节记在谁头上」。 原文的小标题就是内存布局[§4.5, p4]。
10.1 峰值内存记在哪一行
原文给的实测口径:图 5 画的是 MC-smaller-city+ 数据集上、6000 万高斯层级的一次训练迭代的 CPU 与 GPU 峰值内存[Fig. 5 图注, p5;§4.5, p4]。
结论两句,第二句是重点:内存占用的大头被「逐高斯的属性」以及它们对应的 ADAM 优化器状态吃掉;相比之下,层级结构本身只占不到 10%[§4.5, p4]。
「不到 10%」这个数是整套架构的许可证。 它说明:把树结构放进显存、把属性留在 CPU,这个拆法在显存上是划得来的:省掉的是那 90% 的大头,留下的是不到 10% 的小头。如果反过来、层级占了大头,这套设计就不成立。 第 4 章那三句骨架里的第三句「只把树结构放进显存」,依据正是这一句读数。
Peak memory consumption of CPU and GPU for a training iteration on MC-smaller-city+ with 60 million Gaussians.],图里 CPU 与 GPU 两侧分列。②读法:看两侧的量级差,这是「大头在 CPU、小头在 GPU」这一定性结论的唯一图证;别去逐格加总(图给的是分类占比,不是可加严的数表)。
来源:A LoD of Gaussians, Fig. 5, p5 · © 2026 the owner/author(s)(CC BY-NC-ND 4.0)· 原样引用,未修改
10.2 逐高斯的那一半:一份数据分两处放
图 9 给的是逐高斯分解,原文的图注写:只有当前载入的高斯与精简的 SPT 信息需要驻留显存[Fig. 9 图注, p9];(b)部分给出与单个高斯相关的全部数据的分解,以及它们如何在 CPU 与 GPU 之间分布[§4.5, p4]。
这张图的落点在第 3 章(内存账的入口),此处只回扣一句:「哪些字段留在显存」不是随手切的,它等于「按每帧必用与否切」:树结构与 SPT 的 m_d 这几项每帧都要读(要算切),而位置、旋转、尺度、不透明度、球谐系数只在被选中时才需要。切法跟着访问频率走,这是第 9 章缓存同一条道理的第二次出现。
10.3 把它翻成一张驻留策略表
图 4-1 与图 5-1 合起来回答的是同一个问题,但散在两处。 下面把全篇出现过的数据分门别类收进一张表:
| 数据 | 放在哪 | 依据 |
|---|---|---|
上层层级(树结构 + 各节点的 m_d 等切信息) | 显存常驻 | §4.3「用 BFS 切上层层级」;A.7 伪码里的 upper_cut |
| skybox 高斯 | 显存常驻 | §4.4「以及 skybox 高斯(它一直留在 VRAM 里)」 |
| 已载入的 SPT 切 + 各自的距离 d̄ⱼ | 显存缓存,LRU 写回、每 1000 步清空 | §4.4;图 4-1 |
| 高斯属性(位置/旋转/尺度/不透明度/SH) | CPU RAM,按 Morton Z 序存 | §4.1;A.5「Gaussian Order」 |
| ADAM 优化器状态 | CPU RAM | §4.5(占 RAM 的大头) |
| 训练图像 | 磁盘,每个迭代现读 | A.5「Training Images」 |
这张表有两个值得停一下的格子。 ① skybox 常驻显存:天空盒高斯数量少、又几乎每帧都可见,留在显存比来回搬划算,它是「常驻」策略里唯一的例外项,例外成立是因为它不随规模增长。② 训练图像从磁盘读:这一格是主动放弃了 VRAM。原文在 A.5 交代得很直白:常规高斯泼溅把整个训练集都放在 VRAM 里换取训练速度,但那在消费级硬件上训超大场景是不可行的;所以我们每个迭代都从磁盘读真值图像,用训练性能换显存[A.5, p17]。
10.4 这笔账与第 3 章的 800 字节对得上吗
原文在 §6 的局限里给了一条很实用的口径:我们的方法大约每百万高斯需要 1 GB 的 RAM[§6, p7]。
把它换成单高斯口径,再与第 3 章那笔账对齐(这一步是本站自己算的,原文没有并列给出这两个数):
| 口径 | 单高斯成本 | 说明 |
|---|---|---|
| 第 3 章(显存侧,运行时驻留) | 约 800 B | 属性 + 优化器状态 + 前向/反向的临时分配 |
| §6(RAM 侧,全量常驻) | 约 1 GB ÷ 10⁶ ≈ 1.07 KB | 含层级结构(< 10%)与 SPT 信息 |
两个数相差约三成,方向也对得上:800 B 是同时驻留的那部分成本,1.07 KB 是整份模型摊到每个高斯的成本,后者多出来的正是那不到一成的结构开销与对齐损耗。按 6000 万高斯反推,RAM 一侧约 60 GB,这个量级才解释得通「为什么要在消费级显卡之外的、大内存的工作站上跑」。
这一章最后要补一句反向的代价,它把第 1 章的缺口补完整。 原文在 §6 承认:每百万高斯约 1 GB RAM 的口径虽然比前人高效,仍然约束了极大场景的可扩展性;从磁盘加载在实验里可行,但代价是约 10 倍的减速,所以快速的二级存储非常值得期待[§6, p7]。
这句话的形态值得记住:本篇没有消掉成本,它做的是把成本从「显存装不下」换成「搬运慢」,再用 LoD 与缓存把它压回可用区间。第 3 章那堵墙被绕过去了,但绕的方法是把墙搬到了 RAM 与磁盘上,这是「外存」这个词的全部含义,也是这一章的分量所在。
11主结果:画质、显存、帧率三条线
这一章把两张主表逐格算一遍。 表 1 是本篇与四个基线在三个数据集上的正面比较,四列附加信息就是「三条线」里的显存与迭代数;表 2 换到 H-3DGS 与 OccluGaussian 两套数据集上再比一次。
11.1 先把表 1 摆全
原始读数(表 1, p5)如下,本节所有结论都从这里算:
| 数据集/方法 | PSNR↑ | SSIM↑ | LPIPS↓ | VRAM 渲染↓ | VRAM 训练↓ | #迭代↓ | #高斯 |
|---|---|---|---|---|---|---|---|
| MC-small-city+(42.2k 图) | |||||||
| CityGaussian | 19.78 | 0.650 | 0.475 | 2.4GB | 4.1GB | 1.11M | 2.7M |
| HorizonGS | 12.06 | 0.521 | 0.544 | 20.6GB | 25.3GB | 2.5M | N/A |
| OctreeGS | OOM | OOM | OOM | OOM | OOM | OOM | OOM |
| H-3DGS† | OOM | OOM | OOM | OOM | OOM | OOM | OOM |
| CLM | 15.68 | 0.584 | 0.523 | 18.7GB | 25.1GB | 600k | 24.2M |
| Ours | 21.59 | 0.711 | 0.396 | 16.4GB | 18.0GB | 600k | 136.7M |
| MC-smaller-city+(15.1k 图) | |||||||
| HorizonGS | 15.28 | 0.601 | 0.435 | 13.9GB | 23.6GB | 1.2M | 34.1M |
| OctreeGS | 15.93 | 0.560 | 0.556 | 26.6GB | 98.7GB | 310k | N/A |
| Ours | 21.71 | 0.710 | 0.370 | 15.7GB | 17.2GB | 310k | 60M |
| H-3DGS† | 14.57 | 0.516 | 0.563 | 97.0GB | 15.1GB | 4M | 83.1M |
| Ours† | 20.59 | 0.658 | 0.468 | 20.7GB | 22.1GB | 310k | 24.7M |
| Uni10k(10.1k 图) | |||||||
| CityGaussian | 19.78 | 0.642 | 0.414 | 3.7GB | 14.6GB | 300k | 2.2M |
| H-3DGS | 19.96 | 0.705 | 0.319 | 39.2GB | 26.5GB | 255k | 32.5M |
| OctreeGS | 20.06 | 0.602 | 0.341 | 25.3GB | 22.9GB | 160k | N/A |
| CLM-GS | 19.89 | 0.608 | 0.455 | 46.7GB | 39.7GB | 160k | 12.6M |
| HorizonGS | 21.72 | 0.722 | 0.326 | 10.3GB | 44.3GB | 400k | N/A |
| Ours | 21.32 | 0.718 | 0.336 | 22.6GB | 31.3GB | 160k | 28.6M |
读表之前先记住表注里的一条硬规则:超过 141 GB 显存即判定 OOM[表 1 注文, p5]。这一条决定了「OOM」那几格该怎么读(见 11.3 节)。
11.2 六笔账
账一:MC-small-city+ 上,唯一跑完又不糊的强方法就是它自己。 表里 OctreeGS 与 H-3DGS 整行 OOM;跑完的三个里,最高的 CityGaussian 只拿到 19.78,而它的高斯数只有 2.7M,这是把训练出来的高斯丢掉约九成换来的「无接缝」,代价是画面糊(口径见 12.4 节)。Ours 的 21.59 比它高 1.81,高斯数是 136.7M 对 2.7M[表 1, p5]。两个数差了一个半数量级,说明这一格不是靠「少放东西」换来的。
账二:OOM 那两行是本章最硬的证据。 141 GB 的判定线意味着 OctreeGS 与 H-3DGS 在那张卡上都没训完 MC-small-city+;而本篇在 18.0 GB 训练显存下做完了同一件事[表 1, p5]。这已经超出「快一点」的范围,是「能不能做」的差别:表 1 里唯一一处用「有无」而不是「高低」来分胜负的地方。
账三:迭代数上的赢面。 Ours 600k,HorizonGS 2.5M,CityGaussian 1.11M[表 1, p5]。原文的判词是:无缝训练还带来更快的收敛,显著减少了所需训练迭代数[§5.1, p5]。原因可以自己推:切块方案里每块要各自收敛,合并后还要再加工(CityGaussian 甚至丢掉九成高斯),而本篇是一个全局模型在持续优化,不必为「接缝对齐」额外花迭代。这也是第 1 章那句「接缝不是规模的必要代价」在时间账上的对应。
账四:Uni10k 上它只赢一半,这一格要老实写下来。 该栏里 HorizonGS 的 21.72 略高于 Ours 的 21.32,SSIM 的 0.722 也高于 0.718,LPIPS 的 0.326 也优于 0.336[表 1, p5]。原文自己交代了原因:HorizonGS 本就是为「街景+航拍混合」这类场景设计的,且依赖真值标签把致密化主要导向街景;而本篇的通用做法(不加额外监督)在 Uni10k 上紧咬它,在两个 MC-city+ 场景上则大幅超过它[§5.1, p6]。
账五:那个「略高」的 21.72 有一张看不见的账单。 原文写:渲染那个神经表示并不实用,因为它有一个昂贵的前置步骤:虽然显存占用低,但每帧渲染时间高达 10 秒[§5.1, p6]。10 秒一帧与「交互式」相距十万八千里,所以 Uni10k 那一格里的 PSNR 最优项在可用性上不成立。这也解释了它 VRAM(渲染)只有 10.3 GB 的原因:神经表示把负担从显存推到了计算。[表 1, p5]
账六:本篇的显存从来不是最小的。 Uni10k 上 22.6 GB 渲染/31.3 GB 训练,高于 CityGaussian 的 3.7/14.6;MC-small-city+ 上 16.4/18.0 GB 也不是最低[表 1, p5]。所以本篇的优势不是「省显存」,而是「在不切块的前提下,把画质做到这个水平,并且训练跑得完」。 这一点在第 12 章的表 8里会被抽象成一行特征对照。
最后补一条本节自己的复算:把三栏里 Ours 与「可用基线中最好」的差列出来:MC-small-city+ +1.81(对 CityGaussian 19.78)、MC-smaller-city+ +5.78(对 OctreeGS 15.93)、Uni10k −0.40(对 HorizonGS 21.72)。三栏两胜一负,胜负的分布不是随机的:赢在「街景+航拍+多尺度」的场景上,输在「别人专门为它设计的场景」上。
11.3 表 2:换两套数据集还成不成立
表 2 换的是 H-3DGS 与 OccluGaussian 两套数据集,读数如下(表 2, p6):
| 方法 | Small City (5.8k) PSNR/SSIM/LPIPS | Campus (22.0k) | Canteen (8.6k) | Classbuilding (9.1k) |
|---|---|---|---|---|
| OctreeGS | 19.20 / 0.601 / 0.498 | 20.54 / 0.643 / 0.544 | 21.49 / 0.826 / 0.293 | 23.08 / 0.889 / 0.197 |
| CityGS | 21.40 / 0.692 / 0.383 | 19.47 / 0.645 / 0.531 | 20.41† / 0.794† / 0.275† | 20.48† / 0.840† / 0.244† |
| H-3DGS | 24.35 / 0.788 / 0.273 | 17.84 / 0.610 / 0.467 | 22.71† / 0.825† / 0.178† | 23.87† / 0.881† / 0.128† |
| CLM-GS | 22.54 / 0.699 / 0.392 | 16.60 / 0.613 / 0.558 | 23.13 / 0.864 / 0.168 | 22.89 / 0.892 / 0.159 |
| OccluGS | N/A | N/A | 25.25† / 0.900† / 0.100† | 25.33† / 0.921† / 0.083† |
| Ours | 24.61 / 0.774 / 0.297 | 21.85 / 0.707 / 0.456 | 23.33 / 0.867 / 0.155 | 24.14 / 0.915 / 0.116 |
逐场景定出胜负数(「最好的基线」按 PSNR 取):
| 场景 | 最好的基线 | Ours | 差 | 赢/输 |
|---|---|---|---|---|
| Small City(街景) | H-3DGS 24.35 | 24.61 | +0.26 | 赢 |
| Campus(街景) | OctreeGS 20.54 | 21.85 | +1.31 | 赢 |
| Canteen(室内) | OccluGS 25.25† | 23.33 | −1.92 | 输 |
| Classbuilding(室内) | OccluGS 25.33† | 24.14 | −1.19 | 输 |
四格两胜两负,而两处负的两格有一个共同点:对手是 OccluGaussian,且那两格的数带 †。表 2 的注文说明 † 号的含义是取自原作者自报的结果(其代码尚未公开)[表 2 注文, p6];而原文在 §5.1 引这类数时也点明因为 OccluGaussian 尚未放出代码,只能拿它自报的结果比[§5.1, p5]。所以这两处负,比的是「本篇自己的训练结果」对「对手自报的数」,口径并不对称。
原文对这一节给出的判词相当克制:在 OccluGaussian 数据集上的结果进一步展示了向室内环境的泛化能力,而室内环境对分治类方法尤其困难[§5.1, p6]。它没有说「我们最好」:在 Canteen 与 Classbuilding 上都输给了 OccluGS,正文照此写。
还有一条评测口径要跟着带上:本篇全部实验跑在 RTX 3090 上,唯独 Uni10k 因为 4K 训练图需要更多显存而例外;把分辨率降到 HD 后,同样参数下峰值显存降到 20 GB[§5.1, p6]。这一条把「单张消费级卡」这句主张落到了型号上:RTX 3090 是 24 GB 的消费级卡。
11.4 渲染侧:LoD 与缓存在推理时也管用
这一节的落点是图 13-1,它的对手与前面都不同。 原文写:我们的 LoD 与缓存策略也能用来高效渲染训好的模型;作为补充材料,我们附上在 RTX 3090 上渲染的评测场景穿行视频;表 1 展示了渲染测试图时相对其他 3DGS 方法的有效显存削减;图 13 比较了我们的 LoD 方法与全细节 3DGS 及 gsplat 的渲染显存与画质;我们的方法在显著降低显存的同时,达到与基线相当的视觉保真度[§5.1, p6]。
Comparison to standard 3DGS and gsplat in terms of rendering quality and VRAM usage on the MC-small-city+ scene.],分 (a)Overall/(b)Aerial View/(c)Street View 三栏。②读法:横轴是显存、纵轴是画质,看曲线往左上走多少:靠左上 = 同样画质更省显存。注意这张图的对手是全细节 3DGS,不是切块方法,所以它的论点是「省内存不降质」,不是「比谁画质高」。
来源:A LoD of Gaussians, Fig. 13, p10 · © 2026 the owner/author(s)(CC BY-NC-ND 4.0)· 原样引用,未修改
这里有一句话要读准:原文说的是「视觉保真度相当」(comparable)而不是更高[§5.1, p6]。图 13 与图 12 回答的是两个不同的问题:图 12 是与分治方法的画质比较,图 13 是与全细节 3DGS 的「省内存代价」比较。两张图不能合并成一句「比 3DGS 好」。
11.5 定性对照:三场景、四方法
图 12 是三场景、四方法的定性对照,图注列出的方法集是 Kerbl et al. 2024/Liu et al. 2024a/Ren et al. 2024/Zhao et al. 2026(即 H-3DGS、CityGS、OctreeGS、CLM-GS)[Fig. 12 图注, p10]。
原文对这张图的判词集中在「伪影」二字上:H-3DGS 的输出有显著的漂浮物与鬼影;虽然 H-3DGS 在 MC-smaller-city+ 的单个块上表现不错,但过大的漂浮物活过了合并流程,遮住了大部分测试图像(参见图 7);漂浮物与鬼影在其他场景的结果里也能看到;CityGaussian 的合并流程(为纯航拍数据集设计)丢掉了大部分训练出的高斯以避免块伪影,结果大多无伪影、显存需求低,但画面明显变糊[§5.1, p5]。
这段话把第 2 章那两条路各自的下场写全了:切块 ⇒ 伪影,而且是训练时看不见、合并后才炸的那种;丢高斯避伪影 ⇒ 糊。本篇要的是第三种:既不切、也不丢,靠 LoD 与流式把「全量模型 + 全量视角」训完。 到这里,第 1 章那句话才算有了账面支撑:三条线里画质与「跑得完」都站住了,帧率这条线还没站住,那要等到第 12 章的表 3-1。
12消融、数据集与边界
这一章把附录的主要内容并进来。 本篇主文 6 页、附录 8 页(A.1–A.7),附录独占了 11 张图与 5 张表,这些内容不能丢,也不足以各立一章,所以按「问题」分成六节:两节消融、一节有效性验证、一节数据集与评测口径、一节实现决定、一节边界。
12.1 消融一:缓存与视锥剔除各值多少(表 3-1)
口径先说清:我们用录制下来的相机路径做消融,表 3 报告这些路径上的平均帧时间;其中 Campus 上评了两个模型(3800 万与 8000 万高斯);训练消融则测 1000 步的平均迭代时长[§5.1, p6;表 3 注文, p6]。原始读数如下:
| 项 | MC-smaller-city+(60M) | MC-small-city+(136M) | Campus(38M) | Campus(80M) |
|---|---|---|---|---|
| Render Full | 48.1 ms | 68.3 ms | 47.1 ms | 83.2 ms |
| Render w/o Cache | 119.4 ms | 127.4 ms | 92.6 ms | 222.3 ms |
| Render w/o Frustum Culling | 52.3 ms | 89.3 ms | 38.3 ms | 110.2 ms |
| Training Full | 156 ms | 174 ms | 205 ms | — |
| Training w/o Cache | 471 ms | 257 ms | 244 ms | — |
| Training w/o Frustum Culling | 685 ms | 626 ms | 312 ms | — |
| Render Cut(HSPT) | 31.9 ms | 45.7 ms | 31.3 ms | 36.5 ms |
| Render Cut(BFS) | 47.8 ms | OOM | 40.0 ms | 53.7 ms |
(表 3 的两栏训练消融在 Campus 上只给了 3800 万那一列,8000 万那一列原文未给数;— 是本站照录的缺格,不是零。)
账一:缓存对渲染的收益,换算成倍数是 1.87–2.67。 119.4→48.1(2.48×)、127.4→68.3(1.87×)、92.6→47.1(1.97×)、222.3→83.2(2.67×)[表 3, p6]。原文的判词正是这一句:缓存显著提升渲染性能,跨场景大致把帧率翻倍[§5.1, p6]。
账二:缓存与视锥剔除在训练上的收益比渲染大得多。 关缓存后:471→156(3.02×)、257→174(1.48×)、244→205(1.19×);关视锥剔除后:685→156(4.39×)、626→174(3.60×)、312→205(1.52×)[表 3, p6]。移除视锥剔除的惩罚比移除缓存更重,原因原文给了:视锥剔除的收益随场景规模放大:在完整的 MC-small-city+ 上平均有 2450 万个高斯被剔除(减少 88%),而 Campus 与 Small City 分别是 980 万与 790 万(减少 74% 与 65%);因此视锥剔除的开销随场景规模摊薄,使它成为最大数据集上不可或缺的一环[§5.1, p6]。
账三:HSPT 切比 BFS 切快,而且在最大场景上 BFS 直接爆显存。 HSPT 31.9/45.7/31.3/36.5 ms 对 BFS 47.8/OOM/40.0/53.7 ms,倍率 1.28–1.50[表 3, p6]。原文写:HSPT 因为并行化更好而一致地给出更快的切时间;而且 BFS 需要所有高斯的位置与尺度都驻留内存,在 MC-small-city+ 上会超过 24 GB 显存,而 HSPT 峰值 21 GB[§5.1, p6]。这一格给第 6 章那条「堆条件」补了第二个理由:BFS 不只是慢,它要求全量属性进显存,与第 4 章「属性留在 CPU」的骨架正面冲突。两条理由合起来,才说明为什么必须换结构。
账四(一处反例,原文自己写了):在最小的那个模型上,视锥剔除是负收益。 Campus 3800 万那一列里,Render w/o Frustum Culling 的 38.3 ms 反而快于 Render Full 的 47.1 ms,也就是剔了反而慢 18.7%[表 3, p6]。原文对此的说法是「符合预期:视锥剔除的开销随场景规模摊薄」[§5.1, p6]:换句话说,当模型还小的时候,这层剔除的固定开销还没被摊平。这一格提醒:本篇的每一项机制都有一个「规模门槛」,门槛以下它是有害的(第 12.6 节会再收一条同类)。
12.2 消融二:缓存与视点调度省了多少搬运(表 4-1)
口径:为验证缓存与视点选择的有效性,我们在 MC-smaller-city+ 上做了一次实验(10 万次迭代、最多 3000 万高斯),分别开启与关闭视点选择与缓存[A.1, p11]。读数:
| 配置 | PSNR↑ | SSIM↑ | LPIPS↓ | #Loaded(平均每次迭代从 RAM 载入的高斯数) |
|---|---|---|---|---|
| w/o caching | 21.831 | 0.701 | 0.425 | 1,629,187 |
| w/ caching | 21.829 | 0.700 | 0.429 | 290,572 |
| w/ view selection | 21.825 | 0.697 | 0.432 | 89,451 |
这笔账值得自己算一遍,因为它是全篇最干净的一处「用多少画质换多少搬运」:
| 量 | 从 | 到 | 变化 |
|---|---|---|---|
| PSNR | 21.831 | 21.825 | −0.006 |
| SSIM | 0.701 | 0.697 | −0.004 |
| LPIPS | 0.425 | 0.432 | +0.007(变差) |
| #Loaded | 1,629,187 | 89,451 | ×0.0549 ⇒ 降 94.5% |
两级各贡献多少也分得开:缓存单独 1,629,187 ÷ 290,572 = 5.61×;视点选择再加 290,572 ÷ 89,451 = 3.25×;合计 18.22×:与原文那句「降低了将近 20 倍」吻合[A.1, p11]。画质侧的总代价是 0.006 PSNR,原文的判词即「画质指标几乎不受影响(PSNR 最大差 0.006)」[A.1, p11]。
一句话把这一节收住:用 0.006 PSNR,换 18 倍的搬运量。 这就是第 9 章那套缓存在账面上的分量。但有一条要跟上:表 4 是在 3000 万高斯/10 万迭代的配置上做的,与表 1 里 Ours 的 6000 万/310k 不是同一配置[A.1, p11]:它是消融,不是主结果,它的 PSNR 不能拿去和表 1 比。
12.3 LoD 与缓存的有效性(图 16-1、图 11-1、图 15-1、图 14-1)
LoD 系统到底有没有用?原文的操作定义是「砍一半看画质掉多少」。 实验设计:每个数据集随机挑 5 张图,在 50 个不同的细节层下比较画质指标与渲染出的高斯数;结果是图 16;另外附在 H200 上用预热缓存渲染该视角 10 次的平均 FPS[A.1, p11]。
结论四句,第二句是判据:① FPS 与高斯数大致成反比(符合预期);② 绝大多数情况下,提高 LoD 档位能一致地改善渲染质量;③ 总体而言,把高斯数减少 50% 时只观察到轻微的质量下滑,这验证了 LoD 结构的有效性;④ 使用连续而非离散的细节档,带来图 16 里曲线的平滑,说明档位之间过渡平滑,从而减少了跳变(popping)[A.1, p11]。
Qualitative evaluation of our LoD system for 5 randomly chosen views and 50 different levels of detail.],分 (a)MC-small-city+ aerial/(b)MC-small-city+ street/(c)Campus 三栏。②读法:横着看同一格从粗到细的变化:找「质量从哪里开始不再明显变好」,那个拐点就是「够用的 LoD 档」。别只看画质:本图的论点是「过渡是否平滑、拐点是否靠前」。
来源:A LoD of Gaussians, Fig. 16, p12 · © 2026 the owner/author(s)(CC BY-NC-ND 4.0)· 原样引用,未修改
图 11 是关于「过渡」的独立证据。 图注原话是「分层 SPT 使细节表示与粗糙表示之间的过渡平滑」[Hierarchical SPTs enable smooth transitions between detailed and coarse representation.][Fig. 11 图注, p9]。
缓存该开多大?图 15 给了一条实用曲线。 图注是「MC-small-city+ 与 Campus 场景在不同缓存大小下渲染 1000 帧相机路径的平均 FPS」[Fig. 15 图注, p11]。原文的判词:曲线显示性能随缓存增大而陡升,直到超过每次迭代通常需要的高斯数后开始走平[A.1, p11]。
图 14 则把 LoD 的机制直接摊开。 图注是「为一帧 MatrixCity 渲染出的 SPT,用不同颜色区分」[Fig. 14 图注, p10]。
12.4 数据集、评测口径与更小的场景
先看最主要的那个基准怎么造出来的。 原文写:对于主基准 MC-small-city+,我们把 MatrixCity 数据集小城场景的 33 006 张街景图与 7 672 张航拍图聚合起来,并另外生成 533 张高海拔视角;重建质量在一组独立的 4 228 个测试视角上评测;场景因为规模巨大、视角稀疏、尺度变化剧烈而极具挑战;稀疏点云由街景与航拍两份点云合并、再随机降采样 5 倍;不使用数据集提供的真值深度图[A.3, p11]。
The MC-small-city+ dataset spans hundreds of buildings, which are supervised by tens of thousands of views, varying widely in scale.],旁边配相机分布(见 A.3 正文「图 17 给出了场景与相机分布」)。②读法:看相机分布本身:街景一圈贴地、航拍在几个高度层,这个「高的很高、低的贴地」的分布就是本篇要解的那道题;如果分布是单一高度,第 12.6 节的 B 类边界就会生效。
来源:A LoD of Gaussians, Fig. 17, p13 · © 2026 the owner/author(s)(CC BY-NC-ND 4.0)· 原样引用,未修改
这里有一处数字对不上,必须照录。 按 A.3 给出的三个分项相加:33 006 + 7 672 + 533 = 41 211 ≈ 41.2k;而表 1 与 §5 都把该场景的图数标为 42.2k[A.3, p11;表 1, p5;§5, p5]。两者差约 1 000 张(约 1.0k)。原文没有解释这个差,本站照录,不作调和,它不影响任何结论(表 1 的胜负与显存读数与该图数无关),但读表时若自己加总,会得到 41.2k 而不是 42.2k。
原文还专门解释了「为什么这个基准上的画质指标这么低」,三条原因[A.3, p12]:
- 对手只评航拍视角,而航拍不到场景图像的 20%、且一般更容易重建;
- 把街景、航拍与新生成的高航拍放在同一个场景里重建,比只重建航拍难得多;
- 有些对手用了 MatrixCity 的真值深度图或稠密点云(几乎包含整场景的真值几何),原文认为这是一种不现实的便利;而本工作从同一份点云降采样 5 倍开始。
第三条最要紧:它说明表 1 里那批数字不是「同一道题上的分数差」,而是「不同的题」。原文还给了一句关于「同时训近景与远景」的判词:在没有像本篇这样的 LoD 系统时,同时训练远近视角会显著劣化两者的画质[A.3, p12]。
再看第二个基准 Uni10k,它是本篇自己造的。 原文写:为补上「跨多种尺度采集的真实大规模数据集」这个缺口,我们提出 Uni10k;场景是一个约 100 000 m² 的户外校园,同时从地面与空中拍摄;在这个尺度上常规 COLMAP 重建通常要数周,为此我们用空间与时间先验配合由粗到细的方案:用 GPS 把图像匹配的复杂度从二次降到近线性(把比较限制在预设的空间半径内);利用「帧来自视频序列」这一时间先验,先均匀每秒采样一帧重建一个基线模型,再增量式地配准、三角化并只用局部 BA 精化,最后做数轮全局 BA;最终重建超过 10 000 张 4K 图像与 620 万个稀疏点,整体 MRE 约 0.63 像素;按字母序每 8 帧留一帧作测试[A.3, p12–p13]。
Uni10K's sparse point cloud. The scene is reconstructed from more than 10 thousand 4k images at widely varying heights, both from aerial and ground perspective.]。②读法:看点云的疏密与高度分层,它是「这个基准为什么难」的物证;也顺便验证 12.4 节那条「6.2M 稀疏点」的量级。
来源:A LoD of Gaussians, Fig. 18, p13 · © 2026 the owner/author(s)(CC BY-NC-ND 4.0)· 原样引用,未修改
另外三处数据集口径要一起带上[A.3, p13–p14]:
- H-3DGS 数据集:原作者没有引入测试划分,所以本工作按字母序每 100 张留一张做测试;并按官方说明关闭曝光优化;仅在这个数据集上使用与 Kerbl 等 [2024] 相同的深度监督。
- OccluGaussian 数据集:三个大规模室内场景;Gallery 场景官网的下载链接是一个损坏的 zip,且未收到作者回复,因此无法评测该场景;Canteen 场景也有部分相机位姿文件里引用的训练图未包含在下载包中,本工作在所有提供的图上以全分辨率运行。
- Mill19 与 UrbanScene3D:相机位姿与稀疏点云取自 Liu 等 [2024a],并按照基线把全部图像降采样 4 倍;收录这两个数据集是因为它们在大规模新视角合成里被广泛使用,同时它们代表本方法的最坏情形:规则、同高度的航拍视角让本方法的 LoD 收益失效,而且可以平凡地切成独立块。
Overview of the aerial and street datasets.],含 (a)Rubble(Mill19) 与 (b)Campus(H-3DGS) 两格。②读法:看视角高度的整齐程度:(a)那种「整齐同高」正是原文自认的最坏情形(LoD 无用、也易切块);(b)是街景为主的对照。这张图是「LoD 的门槛在哪里」的图证。
来源:A LoD of Gaussians, Fig. 19, p15 · © 2026 the owner/author(s)(CC BY-NC-ND 4.0)· 原样引用,未修改
这三处口径连起来读,会看到一条共同做法:凡是别人没给测试划分的,就自己补一个(按字母序等距留出)。 这是评估诚实性的一处细节:它让「重评 H-3DGS」这件事有了依据,也让表 1 与表 2 里 H-3DGS 的数与原论文的数不可直接互比。
接着看两个「更小场景」的结果,它们都对本篇不利,原文照录了。 先看 H-3DGS 的单块数据集(表 5, p13):
| 方法 | Small City Chunk(1.1k)PSNR/SSIM/LPIPS | Campus Chunk(1.5k) |
|---|---|---|
| Mip-NeRF 360† | 24.70 / 0.765 / 0.348 | 20.95 / 0.731 / 0.442 |
| INGP-big† | 23.47 / 0.715 / 0.426 | 20.37 / 0.700 / 0.476 |
| F2-NeRF-big† | 24.53 / 0.762 / 0.342 | 19.25 / 0.681 / 0.478 |
| 3DGS† | 25.34 / 0.776 / 0.337 | 23.87 / 0.785 / 0.378 |
| H-3DGS† | 26.62 / 0.820 / 0.259 | 24.61 / 0.807 / 0.331 |
| Ours | 25.94 / 0.808 / 0.276 | 24.86 / 0.796 / 0.360 |
两格里一胜一负:Campus Chunk 上 24.86 反超 H-3DGS 的 24.61,Small City Chunk 上 25.94 输给 26.62(−0.68)。原文的判词是:在 LoD 结构上训练(这个尺度其实不需要 LoD)「只带来边际的画质下降」[A.3, p13]:措辞是「边际下降」,而数字是 −0.68 PSNR,这一处口径要自己心里有数。
再看 Mill19 与 UrbanScene3D 两套航拍数据集(表 6、表 7, p14):
| 方法 | Rubble(1.6k)PSNR/SSIM/LPIPS/Size | Building(1.9k) |
|---|---|---|
| MegaNeRF† | 24.06 / 0.553 / 0.516 / n/a | 20.93 / 0.547 / 0.504 / n/a |
| 3DGS† | 25.47 / 0.777 / 0.277 / 6.1M | 20.46 / 0.720 / 0.305 / 6.4M |
| CityGaussian† | 25.77 / 0.813 / 0.228 / 9.7M | 21.55 / 0.778 / 0.246 / 13.2M |
| H-3DGS | 24.64 / 0.755 / 0.284 / n/a | 21.52 / 0.723 / 0.297 / n/a |
| Ours | 23.75 / 0.704 / 0.330 / 25M | 20.67 / 0.682 / 0.318 / 25M |
| 方法 | Residence(2.5k)PSNR/SSIM/LPIPS | Sci-Art(3k) |
|---|---|---|
| CityGaussian† | 21.90 / 0.805 / 0.217 | 21.34 / 0.833 / 0.232 |
| 3DGS† | 21.44 / 0.791 / 0.236 | 21.05 / 0.830 / 0.242 |
| H-3DGS | 17.52 / 0.416 / 0.391 | 18.42 / 0.652 / 0.340 |
| OctreeGS | 18.76 / 0.523 / 0.539 | 18.97 / 0.620 / 0.535 |
| Ours | 20.25 / 0.705 / 0.319 | 20.70 / 0.794 / 0.272 |
四格全输:Rubble −2.02(对 CityGaussian† 25.77)、Building −0.88(对 21.55)、Residence −1.65(对 21.90)、Sci-Art −0.64(对 21.34)[表 6、7, p14]。这四格是全书面对本篇最不利的一组数,而原文把它放在附录里、并主动给了原因:「最坏情形」那句话就是为它们写的[A.3, p14]。表 6 的尺寸列也值得看一眼:Ours 是 25M,CityGaussian† 是 9.7M/13.2M:它是用更多高斯、拿到更低画质,这一格输得比 PSNR 差看起来更彻底。
最后看表 8,它把「为什么还要用这套方法」抽象成了一张特征表(表 8-1, p15):
| 方法 | LoD 训练 | LoD 渲染 | 外存训练 | 交互式渲染 | 无切块伪影 | 高斯类型 |
|---|---|---|---|---|---|---|
| CityGaussian | × | √ | × | √ | × | 显式 |
| HorizonGS | √ | √ | × | × | × | 神经 |
| H-3DGS | × | √ | × | √ | × | 显式 |
| OctreeGS | √ | √ | × | √ | √ | 神经 |
| CLM-GS | × | × | √ | × | √ | 显式 |
| VastGaussian | × | × | × | √ | × | 显式 |
| OccluGaussian | × | × | × | √ | × | 显式 |
| Ours | √ | √ | √ | √ | √ | 显式 |
(记号说明:原文这张表用的是「勾」与「叉」两个记号,本站的文本转录按中文技术文惯例记为 √/×,含义一一对应;原图本身仍以「勾」「叉」呈现。)
这张表只该读出一句话:Ours 是五项全 √ 的唯一一行。 其余七行各缺至少一项,而缺的那一项正好是它们上文被判出局的原因:CityGaussian 与 H-3DGS 缺「无切块伪影」(第 2 章那两类伪影)、HorizonGS 缺「交互式渲染」(每帧 10 秒)、CLM-GS 缺两个 LoD 列、OctreeGS 缺「外存训练」(所以它 OOM)。
读这张表有三条纪律,否则会读过头:① 它是一张「有无」表,不是「好坏」表:√ 只表示具备该能力,不代表该能力做得好。② Ours 全 √ 不等于它在每一格都赢:表 2、表 5、表 6、表 7 里有六格它是输的。③ 表里唯一一个数字是「1」(即表 8 的数字 token 只有 1 个),所以本表的核验方式是逐行读格,不是数字复算,这一条在本站台账里已登记。
12.5 实现中的几处关键决定
这一节把附录 A.5/A.6 里那些「不写会看不懂结果」的决定收进来。 它们大多是一句话,但每一句都对应着一个可观测的后果。
| 决定 | 具体做法 | 后果 | 出处 |
|---|---|---|---|
| 代码基座 | 结构基于 H-3DGS:复用它的层级构造器,替换掉切法与分块训练,光栅化器换成 Kerbl 等 [2023] 的;致密化用 Kheradmand 等 [2024] 的实现;全部用 PyTorch 与 C++/CUDA | 「换掉的是哪一部分」说得很清楚:层级构造继承、切割与训练自研 | A.5, p16 |
| LoD 噪声 | 每次迭代把到 SPT 中心的距离乘 1 + 5r⁴,r ~ U(0,1) | 不提测试集画质,但显著改善分布外视角并减少 LoD 跳变 | A.5, p16 |
| 焦距归一 | 用相对距离 d̂ = (fb / fi)·d 做 HSPT 切 | 双倍焦距的相机,切距离应减半:匹配它在像平面上的投影足迹 | A.5, p16 |
| SH 阶 | 大于 1 阶对测试场景的画质贡献不显著;要训更高阶时粗阶段用 0→1 阶、细阶段逐步升到 n 阶(每次升阶安排在总迭代的 10% 之后) | 升阶与训练阶段对齐,避免高阶系数在早期被噪声带偏 | A.5, p16 |
| 高斯排序 | CPU 侧按 Morton Z 序存;每次致密化迭代重排一次 | 利用空间局部性提升访存效率;顺序会随训练变化,所以要跟着致密化重排 | A.5, p16 |
| 训练图像 | 每个迭代从磁盘读真值图,不常驻 VRAM | 用训练速度换显存(第 10.3 节) | A.5, p17 |
| 性能优化 | SPT 的 m_d(i)/m_d(parent(i))/i 存在一块连续的 GPU buffer 里,用优化过的 CUDA 核并行切;高斯属性在 RAM 里按 AoS 存成一个 PyTorch 张量,一次性拷到 GPU 再重排成 SoA(光栅化器要的布局) | 「一次拷、一次重排」是搬运效率的关键,这是第 9 章「省搬运」在实现层的落点 | A.5, p17 |
「LoD 噪声」那一行最值得停一下:原文明确写了它不改善测试集画质(While this does not improve image metrics on the test set),但显著改善分布外视角、减少跳变[A.5, p16]。这与第 9.2 节那句「随机性提升鲁棒性」是同一种记账方式:收益不记在画质栏,记在稳定性栏。 本篇有三处这样的设计(容差、清空缓存、LoD 噪声),它们合起来构成一种态度:先把可用性做出来,再用便宜的随机化换取不脆。
还有一类决定是「明知不完美但选择不动它」,原文单独列了一节。 那就是不可达高斯:训练中可能发生子高斯变得比父高斯更大,于是出现 m_d(parent(i)) < m_d(i) 的情形,使父高斯无法满足 SPT 的切条件;我们清楚这是一处低效,但实测只有少数(< 10%)高斯会这样;它们仍占着一部分 RAM,但从不被渲染或搬运;我们试过在训练中重平衡层级,但代价太高、收益太小;总体上我们认为这比产生非法切集要好,后者会把训练带偏[A.5, p17]。
这段话把第 6 章那个「堆条件」补上了一个不体面的尾巴:它并没有被彻底修好,只是被限制在 10% 以内,并且被证明比「产生非法切集」便宜。 这是全文最诚实的一处工程取舍,也是理解「为什么不能把层级切到完美」的关键。
最后是致密化本身的一处反例,落点是图 21。 原文写:纯用 Kheradmand 等 [2024] 的致密化策略(给每个高斯的位置加噪,并施加不透明度/尺度损失)在大场景上会出问题,因为大多数高斯在任一视角下都不可见:结果是场景密度逐渐消失,或者出现极端的「拉丝」伪影(参见图 21);但如果去掉这些损失来鼓励 respawn,致密化又会变得漫无目的、随机;本工作实现的另一个策略是:只对「在当前迭代中至少影响过一个像素」的高斯施加这些损失与噪声;这显著改善了结果,但MCMC 致密化在低高斯密度下总体表现仍然差,而超大场景恰恰要求低密度;在单块这类小场景上,改过的 MCMC 在预算充足时略优于本篇最终采用的策略,但在更大的场景上落后;避免破坏性的不透明度重置尤其重要,因为很多高斯在不透明度恢复后会不再满足层级结构[A.6, p16–p17]。
Without regularization, the scale- and opacity-losses of 3DGS-as-MCMC lead to either stringing or disappearance of the entire scene.],分 (a)Campus 与 (b)Small City 两格。②读法:看的是「坏成什么样」而不是「好在哪」,这一格是反例图,它证明为什么必须做「只对该迭代有贡献的高斯施加损失」这一处改动。本图在附录页区(p17)。
来源:A LoD of Gaussians, Fig. 21, p17 · © 2026 the owner/author(s)(CC BY-NC-ND 4.0)· 原样引用,未修改
把 12.5 的两条负向结论并排放:不可达高斯(< 10%)留在那里不动,低密度下的 MCMC 致密化靠人为约束兜住。两条都不是「解决了」,而是「选择了代价更小的那一侧」,这正好接上下一节的边界清单。
12.6 边界与反例
末节把原文自己承认的局限、与从数据里读出来的边界收在一处。 每条都给依据,不打折。
| # | 边界/反例 | 依据 |
|---|---|---|
| B1 | Ours 在 Uni10k 上不是最好的:21.32 对 HorizonGS 的 21.72,SSIM 0.718 对 0.722、LPIPS 0.336 对 0.326;而那个 21.72 对应的是每帧 10 秒的渲染,所以「输了一格、赢在可用性」 | 表 1, p5;§5.1, p6 |
| B2 | 两个室内场景输给 OccluGS:Canteen 23.33 对 25.25†(−1.92)、Classbuilding 24.14 对 25.33†(−1.19);且对手那两格的数是自报(代码未公开),口径不对称 | 表 2, p6 |
| B3 | Mill19 与 UrbanScene3D 四格全输(−2.02/−0.88/−1.65/−0.64),原文自认这是最坏情形(同高度航拍让 LoD 失效、且可平凡切块) | 表 6、7, p14;A.3, p14 |
| B4 | H-3DGS 单块的 Small City Chunk 上输 0.68 PSNR(25.94 对 26.62);原文的措辞是「只带来边际的画质下降」 | 表 5, p13;A.3, p13 |
| B5 | Campus 3800 万模型上,视锥剔除是负收益:Render w/o Frustum Culling 38.3 ms 快于 Render Full 47.1 ms | 表 3, p6 |
| B6 | MC-small-city+ 的图数对不上:A.3 的三个分项 33 006+7 672+533=41 211(≈41.2k),而表 1/§5 标 42.2k,差约 1 000 | A.3, p11;表 1, p5 |
| B7 | MC-smaller-city+ 的「约三分之一面积」对不上图数比例:15.1k ÷ 42.2k = 35.8%,按 A.3 的分项口径(15.1k ÷ 41.2k = 36.6%)也仍是三成半 | §5, p5;A.3, p11 |
| B8 | 训练显存不是最低:MC-small-city+ 上 18.0 GB,而 CityGaussian 只要 4.1 GB(代价是丢九成高斯、画面糊);Uni10k 上 31.3 GB 也不占优 | 表 1, p5 |
| B9 | 每百万高斯约 1 GB RAM 仍然约束了极大场景;从磁盘加载可行但代价约 10 倍减速 | §6, p7 |
| B10 | 当整个场景都落在视锥内时,视锥剔除失效;原文指出遮挡剔除(occlusion culling)可以补上这一点(跳过整包 SPT 而不载入) | §6, p7 |
| B11 | 视角距离变化不剧烈的场景里,LoD 机制只带来额外开销(原文举了单高度航拍数据集,指向 Suppl. A.3);这种情况下更直接的做法反而有竞争力 | §6, p7 |
| B12 | 不可达高斯(< 10%)永久占着 RAM,且从不被渲染或搬运;重平衡层级试过,但代价太高、收益太小,被主动放弃 | A.5, p17 |
| B13 | 单次迭代比标准 3DGS 慢(因为有数据加载与层级管理开销),渲染帧率也还没达到全在核内 3DGS 的峰值;原文对此的原话是「这是一个有意识的性能/内存折中」 | §6, p7 |
十三条里,B1–B4 是「画质上真的输」,B5–B7 是「账目上对不上」,B8–B13 是「代价与失效条件」。 三类要分开读:第一类决定方法的适用范围,第二类决定读表时的谨慎程度,第三类决定这套方法什么时候不该用。
最后一句话留给方法本身的定位。 原文在 §6 收尾时写:我们相信外存式 3D 高斯泼溅是把辐射场方法扩展到城市尺度乃至更大场景、并跑在消费级硬件上的一条有前途的方向[§6, p7]。这句用了「有前途」而不是「已经解决」:与 12.6 这十三条边界一起读,才算读完了这一篇。
13这篇论文的五条贡献
- 一个不切块的外存式训练与交互渲染框架:全部高斯属性留在 CPU 内存,只把树结构放进显存,按视角把当前要用的那几个流式搬进来;原文自称是第一个做到「任意视角、不做空间分区、单张消费级 GPU、城市规模」的 3DGS 框架(§1、§4;第 4、9、10 章)。
- 训练中的动态 LoD 层级致密化:借 3DGS-MCMC 的 split 改写成「给一个高斯长出两个子节点」,在优化过程中让层级持续长大,因此不需要先训完再建层级;叶节点死亡时父被兄弟顶替、死亡叶与父一起重挂到待致密节点上(§1、§4.2;第 7 章)。
- 面向高斯泼溅的分层 SPT(HSPT):把大子树压成 Sequential Point Trees,与上层的高斯层级拼成混合结构;切法可并行,且对训练中层级的持续改动保持鲁棒(这句话兑现为「不产生非法切集」,代价是 < 10% 的不可达高斯被放弃)(§1、§4.3;第 5、6 章)。
- 外存执行:缓存感知的流式与视点调度:按整块 SPT 切缓存、按
D_min ≤ dⱼ/d̄ⱼ ≤ D_max的距离比容差命中,配合 k 近邻图上的视点采样与每 128 步注入的随机视角,把跨帧搬运量压低 18.2 倍、画质只掉 0.006 PSNR(§1、§4.4;第 9、12 章)。 - 大规模评测与两个新基准:提出 Uni10k(超过 10 000 张 4K 图、620 万稀疏点、跨地面与空中两个尺度),并把 MatrixCity 小城场景扩成 MC-small-city+(42.2k 图、含 533 张新高空视角);在此之上给出与四个基线的正面对照,以及「六格输、多格赢」的完整账面(§1、§5;第 11、12 章)。
五条里,第 1 条是「能不能做」,第 2、3、4 条是「怎么做成」,第 5 条是「怎么证明」。 值得注意的是第 3 条那个「鲁棒」的落点:它不指向速度,指向「层级被改动之后切法仍然合法」,这正是第 6 章那条堆条件的正对面。五条里有三条是在替同一件事清障:让层级可以在训练中长大。
另有一条不属于贡献、但属于本篇的地基:致密化不再等训练完再做。原文在 §4.2 的交代是,前人先把整个场景训完再建层级,而本篇让层级跟着训练一起长;这一处改动既是贡献、也是麻烦的来源:第 3、6 章的那些条件式,全是为了让「层级会长大」这件事不与「切法要正确」相撞而设计的。
14出处、许可与怎么读这篇
| 项 | 内容 |
|---|---|
| 标题 | A LoD of Gaussians:原文有两套副题,两处不一致,照录不改:所据 PDF v4 首页印 A LoD of Gaussians: Out-of-Core Training and Rendering for Seamless Ultra-Large Scene Reconstruction;arXiv 摘要页 Title 字段印 A LoD of Gaussians: Unified Training and Rendering for Ultra-Large Scale Reconstruction with External Memory |
| 作者 | Felix Windisch、Thomas Köhler、Lukas Radl、Mattia D'Urso、Michael Steiner、Dieter Schmalstieg、Markus Steinberger(Graz University of Technology)· Schmalstieg 另兼 University of Stuttgart,Steinberger 另兼 Huawei Technologies |
| 发表 | Proceedings of SIGGRAPH 2026(arXiv 摘要页 Journal reference 字段)· 19 页(主文 p1–p6,参考文献 p8–p10,附录 p11–p18) |
| 标识 | Related DOI 10.1145/3799902.3811076(与篇目 59 的 10.1145/3799902.3811064 同属 SIGGRAPH 2026 论文集)· arXiv 2507.01110v4 [cs.GR](2026-02-17 修订;v1 为 2025-07-01) |
| 关键词 | Level of Detail、Gaussian Splatting、Large-Scale Reconstruction(原文 Additional Key Words and Phrases)· CCS:Rasterization、Visibility、Machine learning |
| 文字层规模 | 80,310 字符 | 编号式 (1)–(7) | 图 21 张 | 表 8 张 | 伪码 3 则(Algorithm 1/2/3,在 A.7) |
| 授权 | CC BY-NC-ND 4.0(arXiv 摘要页 License 字段为 licenses/by-nc-nd-4.0;PDF 全文没有任何权利块:Creative Commons/Copyright/©/ISBN 等七个关键词全部 0 命中)⇒ 可站内托管原文、可原样引用;不得改作、不得商用。落点三件(含 paper.pdf),卡片 chip 不带 warn |
| ND 落地约束 | 封面不得裁切:thumb.webp 按原生比例等比缩放(本篇 teaser 是通栏宽图,任何裁切都会改动原作者构图) |
| 使用说明 | 正文只对原文作简短引用;摘要为英文原样引用并标页码;29 件图元全部原样零加工引用(未裁切拼接、未加标注、未施滤镜),逐图给出「图号 + 页码 + 出处 + 未修改」四字段署名 |