ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

HAC解读:哈希网格如何将3D高斯泼溅压缩一两个数量级

HAC解读:哈希网格如何将3D高斯泼溅压缩一两个数量级 自己训练过3D高斯泼溅3D Gaussian Splatting模型的人基本都经历过同一个尴尬渲染帧率很爽、效果也不错但磁盘上那个 checkpoint 文件就是这么不讲道理地大。后来我在 ECCV 2024 上读到 HACHash-grid Assisted Context这篇工作它用哈希网格把 3D 高斯压缩这件事从「存一堆无序参数」改成了「存一个紧凑场景结构加小残差」同场景体积能降一两个数量级。这篇技术解读我就围绕 HAC 如何用哈希网格重构 3D 高斯压缩范式展开把它的出发点、技术链路、与同类方法的差异以及实际工程落地的观感逐一讲清楚。想认真搞懂 3D 高斯压缩、或者准备在自己的项目里引入这套方案的读者这篇应该能帮你省不少看论文的时间。1. 为什么原生 3DGS 是“存储灾难”先看无序性从哪来1.1 一个场景里的高斯到底存了些什么3DGS 用一堆三维高斯原语描述场景每个高斯本质上是一个带方向、带大小、带颜色信息的局部椭圆体。打开模型文件你能看到每个高斯都保存着四类信息位置3 个 float决定了这个高斯在空间中落在哪协方差一般拆成尺度3 个 float和旋转4 个 float 的四元数不透明度1 个 float颜色用球谐系数表达常见到 3 阶就是 48 个 float简单加一加一个高斯的属性大概要 55~60 个 float。一个普通室内场景通常有 30 万到 100 万个高斯算下来就是几百万个 float。一个场景几百 MB 的现象就是这么来的。有人可能会问直接像图像压缩那样用 JPEG 的思路处理不行吗问题在于3DGS 没有像像素那样规整的网格结构。像素天然在一个二维规则网格上相邻像素就是空间相邻压缩算法可以轻松利用这种局部相关性。而高斯在空间中是不规则分布的数量也多彼此之间没有显式的连接关系文件里保存的顺序也和空间位置没有必然联系。这种没有邻接结构、没有规则拓扑的数据直接套用传统压缩工具很难榨出多少空间。1.2 “无序”不只是顺序乱而是结构缺失我在调 3DGS 项目时有一次想看看高斯的存储顺序和场景几何有没有关系结果发现把文件里前 1000 个高斯的位置可视化出来它们在空间里分布得相当散。也就是说模型文件在磁盘上就是一份“散装清单”同一个墙面上的几千个高斯在文件里可能隔得非常远。这种无序性带来两个压缩层面的麻烦。第一信息高度冗余但无法被有效识别。同一个平面、同一个物体表面上有大量特征相似的高斯它们的位置、尺度、颜色其实非常有规律。但在无序存储下想找出这些规律需要额外的索引结构这本身就是开销。第二属性之间互相纠缠。一个高斯的颜色、大小、透明度并不是独立随机的它们共同描述了它所在的表面区域。如果压缩时只把它们当作独立数值去量化、去熵编码就浪费了这层空间相关性。传统手法能省掉的只是一些统计冗余但真正占大头的是“同一个区域的高斯在反复记录相似内容”这种结构冗余。1.3 两条压缩路线的分岔事后压缩与重新表达面对 3DGS 的存储问题业内大致分成两个思路。一条是“事后压缩”代表做法是把训练好的高斯基元做量化、剪枝、再用熵编码压缩典型如基于向量量化或标量量化的后处理方案。这类方法改动小、实现快但它把训练好的表示当作既成事实压缩器只能在这个既成框架里找冗余能压缩的幅度有限。好比你有一本完全乱序的词典压缩算法只能把每个词条压一压却没法把重复的释义合并掉。另一条是“重新表达”代表思路是通过架构设计让高斯的属性从一个共享的、紧凑的先验结构中生成这样模型文件本来就该很小。Scaffold-GS 的锚点机制属于这个方向HAC 也属于这个方向。HAC 特别的地方在于它选择哈希网格来充当这个共享先验——这就是标题里“从无序到结构化”的直接含义不再让每个高斯各自为政地保存全部属性而是让所有高斯共同依赖一个哈希网格表达的空间结构。2. 哈希网格如何提供“空间先验”HAC 的核心设计动机2.1 哈希网格并不是新东西从 Instant-NGP 继承的成熟组件提到哈希网格熟悉神经辐射场NeRF的读者应该不陌生。Instant-NGP 用它把一个隐式神经场的训练时间从小时级拉到了分钟级靠的就是“多分辨率哈希编码”。它的核心思路很简单准备一组分辨率从低到高的特征网格每个网格单元里存放一个固定长度的特征向量输入一个三维空间坐标时从低分辨率到高分辨率逐层查询它落在哪个格子取出对应特征插值后拼在一起作为后续网络层的输入。这套机制有一个很反直觉的优势理论上要表达一个连续空间场可能需要很多参数但哈希表允许不同空间位置共享存储槽位实际训练时碰撞并不频繁所以只需要很小的一张表就能承载相当丰富的空间信息。对小规模重建场景来说整个哈希表可能只有几百 KB 到几 MB却能区分非常细的空间特征。这就给压缩一个很自然的起点。既然 3DGS 的高斯分布在一个连续空间里而这个空间本身是可以通过哈希网格被紧凑编码的那么“场景长什么样”这件最占信息量的事情完全可以交给哈希网格去表达不必再让每个高斯重复存一份。2.2 属性从“独立参数”变成“网格特征的衍生结果”HAC 对哈希网格的使用方式和 Instant-NGP 不太一样。即时神经场是用哈希特征做连续场的坐标编码而 HAC 是把哈希特征当作 3D 高斯的“属性预测源”。具体地说HAC 训练了一个小规模的多分辨率哈希网格然后对场景中的每一个高斯都根据它所在的空间位置去查询哈希特征。之后高斯的属性比如不透明度、协方差、球谐系数不再是直接优化的自由参数而是由一个浅层网络或上下文模型基于网格特征和周围已解码信息预测出来的结果。这意味着模型文件里不再需要保存每一个高斯的完整属性集合只需要保存所有高斯的位置集合这部分是必须的因为高斯在空间中的“存在位置”很难被完全压缩掉一小部分高斯的残差信息用来修正哈希特征预测不准的细节哈希网格和预测网络的权重。同一面墙上相邻的两个高斯位置不同但查询到的哈希特征高度相似于是预测出的属性也高度相似。最终编码时这些属性的残差会非常小概率分布非常集中熵编码器的效率会特别高。这正是哈希网格“重构” 3D 高斯压缩范式的关键它把原来每个高斯私有的属性转变成了空间共享特征的函数值。2.3 为什么偏偏是哈希而不是密集栅格或显式锚点有人会问既然要做空间结构先验用规则的密集体素栅格不也可以在实际操作中不太行。3D 场景是高度稀疏的一堵墙、一张桌子、一个房间只占据整个空间体素里极少的一部分密集栅格会浪费大量存储在空气上。而且到了 Mip-NeRF360 这种多尺度数据集上室外场景的空间范围很大密集栅格的分辨率很难兼顾细节和体积。显式锚点方案也能提供结构先验但这需要额外设计锚点位置、锚点密度、邻域半径等一系列几何超参数而且锚点集本身是离散的查询和插值不如哈希网格自然。哈希网格则固定就是那几层表每个坐标都能直接算索引、取特征、做三线性插值整个流程完全可微CUDA 实现也现成。从工程角度看HAC 选哈希网格还有一个隐性好处它把一个通用的、已经被业界验证过的组件拿来做场景结构编码省去了为 3DGS 专门设计拓扑结构的工作量。代码结构上更干净复现门槛也更低。3. 压缩链路拆解属性分组、上下文预测与熵编码如何配合3.1 渐进式结构先解码主干再补细节HAC 的编解码不是一个全属性一次到位的并联过程而是采用渐进式的串联结构。论文里的流程大致是先解码出最基本的结构信息然后在它的基础上逐步预测和补充更细节的属性每一步都依赖上一步已经得到的结果。这种设计和图像压缩里的“先低分辨率图、再补高频残差”的思路一脉相承。具体到高斯属性编码顺序一般按属性的“基础程度”排列先处理位置和高斯总数再逐类处理不透明度、协方差、球谐系数之类的属性。每处理一类属性时编码器会参考已经解码出来的空间结构和属性信息给出当前属性的概率分布估计再结合真实的属性值做算术编码。解码端对称执行这个过程上一轮的预测结果会作为下一轮的上下文输入。这种渐进式的意义在于它把“压缩整个场景”这个大问题拆成了有先后依赖、可逐步修正的小问题。越靠前的步骤越稳定、越容易预测占的比特越少越靠后的细节属性则可以利用前面所有信息把残差压到很小。3.2 上下文模型用邻居和网格特征“猜”出当前高斯上下文模型是整个压缩系统的“预测中枢”。它的输入主要有两类一类是当前高斯的位置对应的哈希网格特征另一类是周围已经解码出的高斯基元的属性信息。输出则是当前属性的一组概率分布参数后续的算术编码器就靠这个分布把真实值编码成比特流。可以把这一步理解成“看图说话”。哈希网格已经提供了空间位置的概要描述等于告诉模型“这里大概是墙壁表面材质偏白平整度很高”。已解码的邻居高斯则提供了更精细的参考比如“附近高斯的透明度都很高尺度比较大朝向基本一致”。那么当前高斯的属性就非常容易被猜中了。如果模型猜得够准熵编码需要的比特数就逼近信息论极限压缩率随之显著提升。值得注意的是上下文模型本身也是轻量级的并不需要很大的网络。它依赖的是高质量的输入先验而不是自身的拟合能力。这种“用结构化先验降低预测难度”的设计是 HAC 压缩率能大幅领先朴素量化路线的重要原因。3.3 熵编码只负责兑现压缩率的最后一公里前两步已经把高斯的属性从“难以预测”变成了“容易预测”但最终能不能存进一个很小的文件要看熵编码这一步。HAC 使用算术编码器和现在很多神经压缩方法一致。算术编码器的输入是每个属性值的概率分布分布越集中输出的平均比特数越少。这里有一个很常见的误解很多人觉得压缩率是熵编码器给的其实不是。熵编码只是把概率分布兑现成比特如果预测得不准分布又散又平算术编码也压不动。HAC 真正厉害的地方在于前面的哈希网格加上下文模型已经把分布变得足够尖熵编码只是完成最后的信息论极限兑现。从率失真角度看HAC 还可以通过调节哈希网格的大小、特征维度、预测网络的容量来实现不同压缩率和重建质量之间的折中。网格越大、特征维数越高预测精度越高、残差越小但网格本身占用的存储也增加网格越小则反过来。这个平衡点在训练时是可调的实际使用时可以根据分发场景灵活配置。4. 和 Scaffold-GS、直接量化放在一起比HAC 赢在哪4.1 Scaffold-GS 的显式锚点与 HAC 隐式网格的差异Scaffold-GS 也走“重新表达”路线。它先在场景中确若干显式锚点每个锚点保存一组局部特征再由这些特征生成周围分布的一组子高斯。这个方案一方面减少了优化自由度另一方面在渲染质量和训练稳定性上比原生 3DGS 更好。但它和 HAC 有本质区别锚点是显式离散的点集锚点之间的邻域关系需要自己维护场景越复杂锚点数量和管理成本越高。HAC 用哈希网格则完全没有这个问题空间位置直接查询特征不需要维护任何拓扑结构多分辨率哈希天然具备不同尺度上的特征表达能力。另一个区别是表达密度。Scaffold-GS 的锚点分布在几何表面附近特征是局部的、稀疏的而哈希网格的特征是连续空间场查询任何位置都能得到有意义的特征这种“连续场”属性对上下文模型的预测特别友好。预测器总是能拿到信息而不是偶尔落到某个锚点覆盖范围之外。4.2 直接量化压缩路线的天花板直接量化路线在工程上最容易实现模型训练完对属性做均匀量化再用熵编码压缩。这套流程最大的优点是通用但它有一个绕不过去的天花板它把高斯基元当作相互独立的对象来处理完全没有利用空间相关性。我做一个类比压缩一本词典时如果每个词条都是独立压缩即使每个词条压得很好整本书的体积降幅也有限但如果先把词典里大量重复出现的词义归纳成一张对照表再让词条引用这张表整本书才能真正瘦下去。HAC 和直接量化的差别就在这哈希网格就是那张“对照表”。以下把这两种思路放在一起看会更直观对比项直接量化熵编码Scaffold-GS 风格锚点HAC哈希网格辅助上下文是否利用空间结构基本不利用利用但依赖显式锚点拓扑利用隐式连续特征场属性存储形式逐高斯独立存储锚点特征生成网络哈希网格预测残差实现复杂度低中中可压缩空间统计冗余结构冗余统计冗余结构冗余统计冗余解码速度快快快哈希查询开销可忽略这样对比就很明显直接量化只走完了压缩流程的下半段自己放弃了最有价值的空间结构信息。4.3 率失真视角下的真实收益论文里的实验基本覆盖了当前 3D 高斯重建常用的几个数据集比如 Mip-NeRF360、Tanks and Temples、Deep Blending 等。整体结论是在同样比特率下HAC 的重建质量普遍优于当时已有的压缩方法反过来在达到相同 PSNR 的前提下HAC 所需的存储量要小得多。印象里比较突出的数据是原始 3DGS 模型在 Mip-NeRF360 这类大规模场景上单场景动辄几百 MB而 HAC 压缩后的重建文件可以压进个位数 MB 量级。具体数值以论文原文和官方开源实现为准但量级差距在那里摆着不是靠调一两个编码参数就能磨出来的。这个收益背后是率失真曲线整体变好而不是单纯牺牲质量换体积。如果只追求小体积很多方法都能做到但率失真曲线很难同时保持住。HAC 之所以有价值是因为它在高压缩率下依然保住了足够的画面细节。5. 实验与工程观感纸面指标之外还要关心什么5.1 数据集上的存储与质量表现只看 PSNR 其实不够实际用下来的感受更直观。几个数据集上 HAC 都表现稳定室内场景因为几何结构规整、高斯基元分布有规律压缩率通常最好大场景室外数据则更考验多分辨率哈希的表达能力好在哈希网格天然支持多尺度能同时覆盖近处细节和远处的大背景率失真表现没有明显崩塌。渲染速度也是个关键考量。哈希网格查询和上下文预测并不会成为渲染瓶颈实际推理时解码出来的高基数与传统 3DGS 相当渲染走的是同样的光栅化管线速度基本不损失。对一些显存受限的终端设备来说压缩后模型体量小了很多反而能在更低的硬件配置上跑起来。有一点值得注意HAC 的训练过程是“为压缩而设计”的不是事后对 3DGS 模型做压缩。这意味着拿到一个已训练好的普通 3DGS 模型不能直接套用 HAC 的编码器去压它需要重新用 HAC 的框架训练一遍场景。对于想做先训练后压缩方案的人来说这一点是硬约束。5.2 训练成本与复现注意事项HAC 在训练时多了哈希网格、上下文模型和熵编码模块训练耗时肯定比原生 3DGS 要高一些但由于哈希网格查询和 MLP 推理本身都很轻量额外开销是可以接受的不像有些压缩方法那样为了腾出几个百分点指标就得数倍的训练时间。对项目来说这个成本基本在可接受范围内。复现时最容易踩的坑有几个。一个是编码和解码两边的归一化策略要完全一致否则算术编解码对不上模型根本解不出来。另一个是哈希网格的学习率设置多分辨率哈希表对学习率比较敏感调太高容易抖动调太低则收敛慢最好先参考作者代码里的默认配置再动手。还有一点是高斯的数量必须在编码前确定并固定下来上下文模型依赖解码顺序任何动态增删高斯的操作都可能破坏自回归式的依赖链。代码层面哈希网格的 CUDA 实现可以直接复用一些开源版本算术编码则一般用 torchac 这类现成库。工程上建议先跑通官方 repo 的完整流程再往自己的渲染代码里集成不要一开始就自己造轮子。5.3 这套方案适合什么项目、不适合什么项目从落地角度给一个判断如果你的场景是统一训练一批重建结果又要分发给大量用户比如在线看房、数字孪生展示、移动端体验那 HAC 的思路会很有价值省的是传输带宽和用户硬盘体验提升非常明显。如果你的目的是在训练时快速迭代想法每次都要重新训练大量临时场景那 HAC 的额外训练链路可能有点重先用普通 3DGS 搭原型会更顺手。对渲染帧率有极端要求的场景哈希查询虽然开销小但加在每一帧的预处理阶段也有一点影响需要衡量收益和成本。说到底HAC 不是万能药它是针对“场景大、要分发、对体积敏感”这类实际需求给出的专门解。想清楚自己的约束条件和瓶颈在哪个环节再决定要不要引入这套方案会更合理。6. 从 HAC 延伸出去的思考可压缩表达比压缩器更重要6.1 HAC 真正改变的不是编码器而是表达方式很多做压缩的人习惯把精力花在改进熵编码器、改进上下文模型这几个环节上但 HAC 给了一个更根本的提示如果从一开始就让表达本身是可压缩的后面的编码环节就很轻松。哈希网格让高斯的属性从“完全自由”变成“空间先验约束下的偏移”这相当于在高斯之间强行建立了相关性相关性一旦存在压缩率自然就能上去。这也解释了一个现象HAC 的性能上限很大程度由哈希网格和属性预测的精度决定而不是由算术编码器决定。编码器只是一个兑现工具真正的信息节省发生在“把无序化为有序”的那一步。这个认识对我自己后来设计其他类型的 3D 表达能力也挺有启发不管参数是体素、网格还是更复杂的结构先问一句“参数之间共享了什么信息”比直接想“怎么把参数压小”更本质。6.2 对 NeRF/3DGS 之外场景表示的启发哈希网格不仅能服务 3DGS它对任何“参数集缺乏空间结构”的表达方式都可能有参考价值。比如动态场景、语义场、甚至是纯粹的几何重建只要数据落在一个连续空间里都可以考虑把大头的表达能力收敛到一个共享编码结构上再用一个轻量预测器还原细节。本质上这跟隐式神经场和显式参数化之间的平衡是同一种思路。这种思想的适用范围其实还在不断扩大。你可以看到很多论文开始把哈希编码当作一个基础设施来用就像卷积神经网络里的 BatchNorm 一样变成标准组件。HAC 只是其中一个把它的价值放到压缩场景下放大的例子但它验证了一个很重要的结论结构化的共享先验是性价比极高的一种压缩手段。6.3 建议的阅读路线与最后一点实操体会如果看完这篇解读想去读原论文我建议按这样的顺序先看摘要和框架图把“哈希网格上下文模型熵编码”这三个模块的位置弄清楚然后直接看实验的率失真曲线先建立“它能压多小”的直观认识最后再回过来抠属性分组和渐进式编码的细节。不建议硬啃每一处公式先抓住主线再逐步补齐支线效率会高很多。就我个人实际体验来说HAC 这类“重新表达”方法比事后压缩方法给人的收获感更强。因为你在复现、在扩展的过程中会不断思考“信息到底存在哪里”。存得越集中格式越结构化后面的存储和传输就越轻松。理解了这一点再回头去看标题里的“从无序到结构化”会发现它描述的不只是 HAC 这一篇文章的技术路线也是下一代场景表示方法绕不开的一个核心方向。
返回列表