GSCodec Studio 中 3DGS Compression Simulation 机制
1. 概述
GSCodec Studio 中的 compression_simulation 是一个训练阶段的压缩感知优化模块。它的目标不是在训练中真正生成码流,而是在训练 forward 和 loss 中提前模拟最终压缩会带来的主要影响,包括参数量化误差、估计码率约束和 SH 高频项稀疏化。
从训练流程上看,它位于真实 post-training compression 之前。训练时模型参数 splats 会先经过 compression simulation,得到一个模拟压缩后的参数副本;随后 renderer 使用这个副本渲染图像,并用渲染误差和估计码率共同优化原始 Gaussian 参数。训练结束后,再用 post-training compression 模块做真正的编码、落盘和解码评估。
核心代码位置:
gsplat/compression_simulation/runtime.py: 新版 simulation 运行时。gsplat/compression_simulation/config.py: 统一配置结构。gsplat/compression_simulation/quantizer.py: 可微量化模拟。gsplat/compression_simulation/entropy.py: 熵模型与码率约束。gsplat/compression_simulation/entropy_model.py: factorized 和 Gaussian entropy model。gsplat/compression_simulation/mask.py: adaptive SH mask。gsplat/compression_simulation/ada_mask.py: annealing mask 实现。examples/simple_trainer.py: 静态 3DGS 训练接入。gsplat/compression_simulation/simulation.py: legacy simulation 和 STG dynamic Gaussian simulation。
2. 使用 Compression Simulation 的目的
3D Gaussian Splatting 的模型主要由大量 Gaussian primitives 组成,每个 Gaussian 包含空间中心、尺度、旋转、不透明度和颜色/SH 系数等参数。未经约束的训练通常会优先追求重建质量,参数分布可能对压缩不友好。例如:
- 参数值分布宽,量化后误差大。
- 高频 SH 系数数量多,存储成本高。
- 部分属性虽然对视觉质量贡献有限,但 entropy coding 下仍然产生较高 bits。
- 训练时从未见过量化噪声,最终压缩后渲染质量容易明显下降。
Compression simulation 的目的就是把这些压缩因素提前引入训练:
-
提高量化鲁棒性
训练过程中 renderer 使用 fake-quantized 参数,模型会主动适应量化误差。 -
优化率失真权衡
loss 中加入rd_lambda * estimated_bits,让模型在图像失真和估计码率之间折中。 -
约束参数分布
entropy loss 会推动参数落到更容易编码的高概率区域。 -
降低高频颜色/视角相关成本
adaptive mask 可以压低或裁剪shN,减少高阶 SH 系数的有效数量。 -
衔接后训练压缩
simulation 不替代 post-training compression,而是让训练结果更适合后续 PNG/VQ/HEVC/entropy coding 等真实编码流程。
3. 总体架构
新版静态 3DGS 使用 DefaultCompressionSimulation 作为统一入口。其内部由三个子模块串联:
raw splats
|
|-- DifferentiableQuantizer
| 对 scales / quats / opacities / sh0 等属性做 fake quantization
|
|-- EntropyConstraint
| 对量化后的属性估计 bits,并返回 entropy loss
|
|-- AdaptiveMask
| 对 shN 做可选稀疏化 mask
|
simulated splats + loss_terms + metrics
从数学上看,这个模块把原本只优化重建质量的 3DGS 训练,改造成一个近似的率失真优化问题。设所有 Gaussian 参数为:
其中 表示 Gaussian 中心 means, 表示 scales, 表示 quats, 表示 opacities, 和 分别表示低阶和高阶 SH 颜色系数。
普通训练优化的是:
其中 是 rasterizer 渲染结果, 是真实图像, 是 L1/SSIM 组合失真。Compression simulation 后,forward 不再直接使用 ,而是使用模拟压缩算子 :
这里:
- 近似真实压缩中的量化和裁剪。
- 是由 entropy model 估计的码率。
- 即配置中的
rd_lambda,控制码率和画质的权衡。 - 约束高阶 SH 系数的有效数量。
因此 simulation 的关键不是“模拟文件格式”,而是把不可导的压缩过程拆成可训练的近似算子,让参数在训练时就沿着压缩友好的方向更新。
4. 配置分析
核心配置类是 CompSimConfig:
@dataclass
class CompSimConfig:
enabled: bool = False
quantizer: QuantizerConfig = field(default_factory=QuantizerConfig)
entropy: EntropyConfig = field(default_factory=EntropyConfig)
mask: MaskConfig = field(default_factory=MaskConfig)
默认支持的静态 3DGS 属性为:
ATTRIBUTE_NAMES = (
"means",
"scales",
"quats",
"opacities",
"sh0",
"shN",
)
默认量化 bitwidth:
| 属性 | 默认 bitwidth | 是否默认量化 | clamp range |
|---|---|---|---|
means | None | 否 | None |
scales | 8 | 是 | [-10, 2] |
quats | 8 | 是 | [-1, 1] |
opacities | 8 | 是 | [-15, 15] |
sh0 | 8 | 是 | [-2, 4] |
shN | None | 否 | None |
默认 entropy steps:
| 属性 | 默认启动 step | 说明 |
|---|---|---|
means | -1 | 不启用 |
quats | 10000 | 10000 step 后加入 entropy loss |
scales | 10000 | 10000 step 后加入 entropy loss |
opacities | 10000 | 配置存在,但新版 entropy 实际未建模 |
sh0 | 20000 | 20000 step 后加入 entropy loss |
shN | 10000 | 配置存在,但新版 entropy 实际未建模 |
典型 YAML:
compression_sim_cfg:
enabled: true
entropy:
enabled: true
model_type: factorized_model
rd_lambda: 0.01
steps:
means: -1
quats: 10000
scales: 10000
opacities: 10000
sh0: 20000
shN: 10000
mask:
enabled: true
start_step: 10000
regularization_weight: 1.0
cap_max: 1000000
learnable:
start_temp: 5.0
end_temp: 0.1
total_iters: 30000
target_sparsity: 0.2
lr: 0.01
5. 可微量化模拟算法
5.1 标量量化模型
对于一个属性张量 x,给定 clamp 范围 [lower, upper] 和 bitwidth b,量化步长为:
例如 quats 默认范围是 [-1, 1],8 bit 时:
真实均匀标量量化可以写为:
如果直接在训练中使用这个 round,forward 与真实量化更一致,但梯度几乎处处为 0,不适合普通反向传播。因此代码提供了两种近似:noise approximation 和 STE approximation。
5.2 Noise 模式
默认模式是 noise。算法为:
这个方法不是真的 round 到离散 level,而是把量化误差建模为均匀噪声。对于高分辨率均匀量化,如果输入在每个量化 bin 内近似均匀,量化误差可近似为:
因此 noise 模式等价于在训练中优化期望失真:
它的优点是 forward 连续、梯度稳定,并且不会把训练过程过早锁死在有限个离散 level 上。论文消融也说明,noise approximation 比 STE-based quantization 得到更好的 RD 表现。
5.3 Round + STE 模式
round 模式更接近真实标量量化:
但 round 不可导,所以 backward 使用 straight-through estimator:
STE 可以理解为把不可导量化算子的 Jacobian 近似为单位矩阵:
这使得训练可以反传,但也带来一个问题:forward 中的参数已经被硬投影到离散点,优化轨迹更粗糙,尤其在 bitwidth 低或参数范围较窄时,搜索空间明显受限。论文 Table IV 中 STE 的 PSNR、SSIM、LPIPS 和最终大小都弱于 noise 模式。
5.4 Warmup Bitwidth
warmup_steps 和 warmup_bitwidth 的作用是控制训练早期的量化强度。量化误差方差与步长平方成正比:
bitwidth 越低,Delta 越大,训练扰动越强。若一开始就施加强量化,几何和颜色还没有收敛时可能被噪声打散。warmup 的意义是先用较温和的量化约束让模型成形,再逐渐进入目标码率设置。
6. Entropy Constraint 算法
6.1 Rate-Distortion Loss
训练主 loss 原本是图像重建项:
开启 compression simulation entropy 后,会额外加入:
其中:
这就是经典 rate-distortion optimization 的拉格朗日形式:
在固定 lambda 下,优化器会自动在两个方向之间折中:
- 如果某个参数显著降低图像失真,即使它带来更多 bits,也可能被保留。
- 如果某个参数对画质贡献有限但熵模型认为它编码代价高,它会被推向更高概率、更低 bits 的区域。
因此 entropy loss 的作用不是简单“让数值变小”,而是让参数分布变得更符合 entropy model 学到的概率结构。
6.2 Factorized Entropy Model
factorized_model 是默认 entropy model。它为每个属性通道学习一个无条件概率分布。输入是量化后的属性值 x 和量化步长 Q,计算量化 bin [x - Q/2, x + Q/2] 的概率质量:
更完整地说,对于第 c 个通道,模型学习一个连续分布的 CDF:
量化后的符号不是点值,而是区间事件:
所以该符号的概率质量为:
对应码长估计为:
其中 psi 是 entropy model 自己的参数,会和 Gaussian 参数一起优化。理想情况下,psi 拟合当前参数分布,而 Gaussian 参数又在 -log p_hat(x) 的约束下向高概率区域移动。两者形成一个交替耦合的过程:
entropy model: 学习参数分布
Gaussian params: 迁移到更容易编码的分布
优点:
- 不需要空间上下文,计算相对简单。
- 可以学习非高斯、非对称的参数分布。
- 适合
scales/quats/sh0这类通道维度较低的属性。
限制:
- 不利用 Gaussian 的空间位置和局部相关性。
- 对不同点之间的上下文依赖建模弱。
6.3 Gaussian Entropy Model
gaussian_model 使用位置相关的条件 Gaussian 分布:
它学习的是条件分布:
其中 pos_i 是第 i 个 Gaussian 的中心位置。直观上,它假设空间邻近或空间结构相似的位置会有可预测的属性分布。比如某些区域的 scale 更集中,某些区域的颜色基底更一致。
为了降低计算开销,代码中只在 means 的 1% 到 99% quantile bbox 内随机采样约 5% 的点估计 bits。这个采样不会改变概率建模形式,但会把 rate loss 从全量估计变成 Monte Carlo 近似:
优点:
- 能利用空间上下文。
- 对具有空间相关性的属性可能估计更准确。
限制:
- 依赖
third_party/gridencoder。 - 训练成本更高。
- 只采样部分点,rate loss 是近似估计。
6.4 当前新版支持范围
新版 EntropyConstraint 中实际建模的属性是:
因此即使配置里写了 opacities 或 shN 的 entropy step,新版 runtime 默认也不会给它们创建 entropy model。这一点和 legacy/STG 分支有所不同。
7. Adaptive SH Mask 算法
3DGS 中 sh0 通常表示 DC/base color,shN 表示更高阶 SH 系数,主要贡献视角相关颜色和高频外观。shN 参数量较大,是压缩中的重要成本来源。
Compression simulation 提供 adaptive mask,用于训练时压低一部分 Gaussian 的 shN。从优化目标看,它近似解决的是:
这里 m_i=0 表示第 i 个 Gaussian 的高阶 SH 被关闭。直接优化二值 mask 是离散组合优化,所以代码使用连续松弛。
7.1 Learnable Mask
learnable mask 为每个 Gaussian 学一个 mask logit:
temperature 随 step 退火:
高温时 sigmoid 更平滑,训练稳定;低温时 mask 更接近二值,方便最终裁剪。
mask loss 可以理解为两部分:
第一项近似 L1 稀疏惩罚,鼓励更少的 SH 激活;第二项把全局激活比例拉向目标值,避免所有 shN 被过度关闭。温度退火让训练早期像连续权重缩放,后期逐渐接近二值选择。
默认 target_sparsity=0.2。注意这里代码中的变量名叫 target_sparsity,但实际 BCE 的目标是 mean(mask),也就是 mask 激活比例。换句话说,它会推动平均 mask 比例接近 0.2。
7.2 Gradient Mask
gradient mask 策略不直接改变 forward 中的 shN,而是对梯度做门控。设第 i 个 Gaussian 的高阶 SH 梯度为 g_i,阈值为 tau。当 shN_i 已经全零且 ||g_i||_2 < tau 时:
这相当于给已经被关闭、且恢复动力不足的高阶 SH 加一个吸收状态。它更像训练规则,而不是显式优化一个 mask 参数。论文消融中它弱于 learnable mask,主要原因是梯度阈值是硬决策,缺少连续优化空间。
8. 对模型的影响
8.1 对几何参数的影响
静态 3DGS 默认不量化 means,所以 Gaussian 中心位置不会被 fake quantization 直接扰动。这有利于保持几何稳定。被直接量化模拟影响的是:
scales: 影响 Gaussian 椭球大小。quats: 影响 Gaussian 旋转。opacities: 影响 alpha blending。sh0: 影响基础颜色。shN: 不默认量化,但可被 mask 稀疏化。
scales 和 quats 参与 entropy loss 后,模型会倾向于学习更容易被低码率表示的尺度和旋转分布。过大的 rd_lambda 可能让 geometry 表达能力下降,表现为细节变糊、边界变软或局部结构不够锐利。
8.2 对颜色和视角相关效果的影响
sh0 量化会直接影响基础颜色。shN mask 会影响视角相关分量和高频外观。如果 mask 太强,可能出现:
- 高光或视角相关颜色变弱。
- 纹理细节降低。
- 某些区域颜色更平均。
但好处是 shN 的有效参数数量下降,后续压缩时能显著降低存储成本。
8.3 对训练收敛的影响
Simulation 引入了额外扰动和额外 loss,因此训练目标更难。仓库默认通过 step schedule 减轻这个问题:
- 早期主要优化图像重建。
- 10000 step 后开启
scales/quatsentropy 和 SH mask。 - 20000 step 后开启
sh0entropy。
这种设计避免模型还没形成基本几何和外观时,就被强压缩约束拉偏。
8.4 对最终压缩质量的影响
训练时加入 simulation 后,最终 checkpoint 通常更适合 post-training compression:
- fake quantization 使参数对量化误差更鲁棒。
- entropy loss 使参数分布更集中、更容易编码。
- mask 使
shN更稀疏,降低高频外观参数成本。
因此在同等码率下通常有更好的重建质量;或者在接近质量下获得更低码率。
9. 参数调节建议
9.1 rd_lambda
rd_lambda 是最重要的率失真权重:
- 较小:更偏重重建质量,码率下降有限。
- 较大:更偏重低码率,可能损失细节和 PSNR。
建议通过多 rate point 实验绘制 RD curve,例如:
bash examples/scripts/static_exps/tt/train_single_ratepoint.sh 0.001
bash examples/scripts/static_exps/tt/train_single_ratepoint.sh 0.005
bash examples/scripts/static_exps/tt/train_single_ratepoint.sh 0.01
bash examples/scripts/static_exps/tt/train_single_ratepoint.sh 0.02
9.2 Entropy step
如果早期开启 entropy,模型可能尚未收敛就被码率约束干扰。默认 10000/20000 step 是一个保守选择。
可以考虑:
- 几何不稳定时,推迟
scales/quatsentropy。 - 颜色质量下降明显时,推迟
sh0entropy。 - 想更强压缩时,提前 entropy 或增大
rd_lambda。
9.3 Mask target
target_sparsity 实际约束的是平均 mask 激活比例。默认 0.2 意味着希望保留约 20% 的 shN 激活。更小会更省码率,但更容易损失视角相关效果。
10. 关键实现片段
这一部分只保留最关键的代码关系,避免把报告变成接口说明。
10.1 训练 step 中的核心调用
simulation_result = self.compression_simulation.run(self.splats, step)
self.comp_sim_result = simulation_result
这一步产生的 self.comp_sim_result.splats 是 renderer 实际使用的参数。原始 self.splats 仍然是被优化器更新的 trainable parameters。
10.2 RD loss 注入点
for loss_name, loss_value in self.comp_sim_result.loss_terms.items():
if loss_name.startswith("entropy/"):
loss = loss + rd_lambda * loss_value
else:
loss = loss + loss_value
这段代码对应数学目标:
其中 loss_value 对 entropy 项来说是平均 estimated bits,对 mask 项来说是 sparsity regularization。
11. 总结
GSCodec Studio 的 compression simulation 是一个典型的 compression-aware training 设计。它通过 fake quantization、entropy loss 和 adaptive SH mask,把后训练压缩中的量化误差、码率成本和高频参数裁剪提前反馈到训练优化过程。
它的核心作用可以概括为:
让 3DGS 不只学会重建图像,也学会以更低码率、更抗量化的参数形式重建图像。
静态 3DGS 新版 runtime 的主线是:
CompSimConfig
-> DefaultCompressionSimulation
-> DifferentiableQuantizer
-> EntropyConstraint
-> AdaptiveMask
-> simulated splats
-> rasterization
-> render loss + rd_lambda * rate loss + mask loss
这种设计不会直接输出最终压缩文件,但会显著影响 checkpoint 的参数分布,使后续 post-training compression 更容易获得更好的 RD 表现。
12. 论文中的 Compression Simulation 消融实验
论文 GSCodec Studio: A Modular Framework for Gaussian Splat Compression 确实包含与 compression simulation 直接相关的消融实验。相关内容主要出现在第 VI-D 节 Analysis of Compression Simulation,并通过 Table IV 和 Table VI 分析训练时 compression simulation 的模块选择和整体有效性。
论文链接:
12.1 论文对 Compression Simulation 的总体结论
论文在方法部分明确把 training-time compression simulation 分成三个组件:
- Differentiable Quantization
- Entropy Constraint
- Adaptive Masking
这与代码中的新版 DefaultCompressionSimulation 完全对应:
DifferentiableQuantizer
-> EntropyConstraint
-> AdaptiveMask
论文指出,学习 3D 表示是欠约束问题:不同参数解可能有接近的渲染质量,但压缩后的大小差异很大。因此,如果训练时没有压缩约束,最终参数可能不是压缩友好的。compression simulation 的目的就是在训练阶段引入 rate-distortion optimization,使最终 Gaussian Splats 更紧凑、更容易压缩。
12.2 Table IV: Compression Simulation 选项消融
Table IV 标题是:
Ablations of our compression simulation options on Tanks&Temples dataset.
该表直接比较了 compression simulation 内部三个模块的不同选择:
| 方法 | 可微量化 | 熵约束 | Adaptive Mask | PSNR | SSIM | LPIPS | Mem. |
|---|---|---|---|---|---|---|---|
| Ours final | Add Noise | Factorized | Learnable | 23.74 | 0.840 | 0.189 | 7.10 |
| Opt to STE-based | STE | Factorized | Learnable | 23.47 | 0.819 | 0.221 | 7.73 |
| Opt to Gauss. model | Add Noise | Gaussian | Learnable | 23.68 | 0.834 | 0.195 | 8.01 |
| Opt to grad. thres. | Add Noise | Factorized | Gradient | 23.62 | 0.839 | 0.192 | 7.28 |
这里的 Ours final 对应最终采用的组合:
noise approximation + factorized entropy model + learnable adaptive mask
这与仓库默认配置相符:
compression_sim_cfg:
entropy:
model_type: factorized_model
mask:
enabled: true
learnable:
target_sparsity: 0.2
12.3 Differentiable Quantization 消融
论文比较了:
- Add Noise
- STE-based quantization
结果:
Add Noise: 23.74 PSNR / 0.840 SSIM / 0.189 LPIPS / 7.10 MB
STE: 23.47 PSNR / 0.819 SSIM / 0.221 LPIPS / 7.73 MB
结论是 uniform noise approximation 优于 STE-based quantization。
论文给出的解释是:
- 两者 backward 都近似传递梯度。
- 关键差异在 forward。
- STE forward 会把参数确定性地 round 到离散候选值,搜索空间更受限。
- noise approximation 在训练时引入随机扰动,后量化值仍能在更连续的空间中探索,因此更容易找到更好的 RD 解。
这也解释了为什么代码中新版 AttributeQuantizerConfig.mode 默认是:
mode: str = "noise"
12.4 Entropy Constraint 消融
论文比较了:
- Factorized density model
- Per-point Gaussian model
结果:
Factorized: 23.74 PSNR / 0.840 SSIM / 0.189 LPIPS / 7.10 MB
Gaussian: 23.68 PSNR / 0.834 SSIM / 0.195 LPIPS / 8.01 MB
结论是 factorized density model 在实验中优于 per-point Gaussian model,尤其是存储大小上约节省接近 1 MB。
论文进一步分析了 entropy constraint 对参数分布的影响:
- 加入 entropy constraint 后,Gaussian 参数分布更紧凑。
- 更紧凑的参数分布意味着更低 entropy。
- 排序后的 quaternion 2D map 更平滑,高频成分更少。
- 这种平滑和聚集会让后续 2D image codec 或 learned entropy coding 更容易压缩。
这与代码中的 EntropyConstraint 对 scales/quats/sh0 估计 -log2(likelihood) 并加入 rate loss 的设计一致。
12.5 Adaptive Masking 消融
论文比较了:
- Learnable mask
- Gradient thresholding
结果:
Learnable: 23.74 PSNR / 0.840 SSIM / 0.189 LPIPS / 7.10 MB
Gradient: 23.62 PSNR / 0.839 SSIM / 0.192 LPIPS / 7.28 MB
结论是 learnable mask 略优于 gradient thresholding。
论文解释:
- Gradient thresholding 是硬决策。
- 一旦某个 splat 是否需要 SH 高频项被梯度阈值决定,灵活性较差。
- Learnable mask 在训练中处于连续空间,最后再二值化。
- mask ratio 通过 KL loss 约束,可以根据内容自适应调整。
这对应代码里的 AnnealingMask:
mask = torch.sigmoid(self.mask_logits / temperature)
return x * mask
训练时 soft mask,测试/保存时可二值化。
12.6 Table VI: 是否使用 Compression Simulation 的整体消融
论文 Table VI 进一步分析 compression simulation 和 post-training compression 的整体有效性:
| 方法 | PSNR | SSIM | LPIPS | #Pts. | #Mem. |
|---|---|---|---|---|---|
| w/o comp. sim. | 24.13 | 0.856 | 0.163 | 1M | 14 MB |
| w/o p.t. comp. | 23.95 | 0.846 | 0.183 | 1M | 236 MB |
| Ours final | 23.74 | 0.840 | 0.189 | 0.7M | 7 MB |
这个表说明:
- 不使用 compression simulation 时,质量指标略高,但压缩后体积约为 14 MB。
- 完整方法质量略降,但体积降到约 7 MB。
- 因此 compression simulation 的主要价值不是提升未压缩质量,而是明显改善最终压缩率。
- 只使用 compression simulation、不开 post-training compression 时,内存仍有 236 MB,说明 simulation 不能替代真实压缩编码。
12.7 论文结论与代码实现的对应关系
论文最终采用的 compression simulation 配置,与当前代码和 YAML 基本一致:
| 论文最终选择 | 代码对应 |
|---|---|
| Uniform noise approximation | AttributeQuantizerConfig.mode = "noise" |
| Factorized density entropy model | EntropyConfig.model_type = "factorized_model" |
| Learnable adaptive mask | MaskConfig.strategy = "learnable" |
| Rate-distortion training | loss += rd_lambda * entropy_loss |
| Post-training compression 仍必需 | post_training_comp_cfg 和 --mode compress |
需要注意的是,论文中讨论了 entropy constraint 对 opacity 的作用,并在 post-training pruning 分析中提到 rate-distortion loss 会推动很多 splats 变成低 opacity。但当前新版 EntropyConstraint 代码实际只为 scales/quats/sh0 建立 entropy model,opacities 在新版 runtime 的 supported_attrs 中被注释掉了。也就是说,论文描述和当前重构代码之间可能存在版本差异;legacy simulation 里也默认把 opacities 的 entropy model 关掉。
12.8 可复现实验脚本线索
仓库中有与这些消融相关的脚本:
examples/benchmarks/compression/mcmc_tt_ablation.sh
examples/benchmarks/compression/final_exp/mcmc_tt_sim_hash_grid.sh
examples/benchmarks/compression/final_exp/mcmc_tt_sim_grad_thres.sh
其中:
mcmc_tt_sim_hash_grid.sh对应 Gaussian entropy model 方向。mcmc_tt_sim_grad_thres.sh对应 gradient threshold adaptive mask 方向。mcmc_tt_ablation.sh是不开 compression simulation 的基线训练再压缩路径。
这些脚本与论文 Table IV/Table VI 的消融设置有明显对应关系。