Spirula Studio VRAM深度剖析splat x img类别与位掩码压缩全解8GB显存训练千万级高斯点【免费下载链接】spirula-studioCross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA.项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studioSpirula Studio 是一个跨厂商的3D Gaussian Splatting3DGS训练器单个自包含二进制文件完成原始照片/视频 → splat → 带纹理网格的完整流程支持 NVIDIA/AMD/Intel/Apple GPUVulkan 或 CUDA 后端并能在8GB 显存中训练 1000 万高斯的完整 SH 模型。这篇文章带你拆解它最耗显存的scratch内存类别——splat x img——以及一套把 572 MiB 压到 13 MiB 的位掩码压缩技术。为什么splat x img是显存的第一大变量训练时GPU 上除了高斯参数本身还有一大堆随训练步数生灭的临时缓冲区scratch。Spirula Studio 用环境变量SS_PROFILE1把所有池化缓冲区自动分桶统计定义在 src/core/PoolSlots.h 中类别大小由谁决定splat高斯数量 Nsplat x img每张图看得见的高斯对数量 C × Nimage图像分辨率appearance / viewer / other外观校正、查看器缓存等关键区别splat类只随模型增长而splat x img 同时随模型和批处理相机数 C 增长。它决定了一个与多张图大量重叠的大场景到底装不装得下是唯一一个又随模型、又随数据增长的类别。读懂 3 个关键数字C×N、nnz、n_isectspacked 投影packed projection一步训练用三个数字描述所有缓冲区都是其中某个的倍数数据来自 docs/notes/vram-splat-x-img.md场景 art_gallery、--cap-max 15000000符号含义实测值C × N投影阶段要测试的 (相机, 高斯) 对总数5 × 1500 万 7500 万nnz通过可见性测试的幸存对数1510 万n_isects光栅化阶段消耗的 (splat, tile) 对数2200 万 ~ 3600 万每个元素各缓冲区的代价2026-08-30 优化后缓冲区每元素字节说明proj.maskC×N / 8可见性位掩码proj.block_count/proj.scan各 C×N / 32每 128 线程工作组 1 次 popcount 及其前缀和proj.screen40 × nnz屏幕行xy、conic、opac、depth、rgbraster_bwd.v_screen40 × nnz反向梯度fp32原子操作需要proj.aabb8 × nnz16 位定点包围盒isect.ids_a/b各 8 × n_isects排序键(tile_id 32) \| depth位掩码压缩572 MiB → 13.42 MiB 的 42 倍缩减packed 投影分两趟第一趟投影全部 C×N 个配对并记录是否可见第二趟只重投影幸存者并紧凑写出。两趟之间的桥梁曾经是一个跨全量 C×N 的int32掩码 一个全量int32前缀和扫描——每对 8 字节在上例中就是 572 MiB总共 3324 MiB 里的 17%外加两遍 C×N 规模的扫描带宽。现在的做法是位掩码几何常数统一放在 src/shaders/packed_mask.h两个后端共用掩码趟把可见性谓词 OR 进工作组共享的位字每个工作组只写1 个 popcount只需扫描 C×N/128 个计数扫描量缩小 128 倍压缩趟用(前面工作组的扫描计数) (本线程之前置位的位数)精确恢复输出槽位。结果每对 8 字节 → 0.16 字节实测 572.20 MiB → 13.42 MiB。⚡ 一个有趣的工程细节两趟 kernel 必须以SS_PMASK_BLOCK线程启动否则位→字的映射会静默错位——所以这个常数放在共享头文件里而不是在两个后端各写一份。阶段竞技场Phase Arena互斥缓冲区共享同一块内存isect.ids_a/b在do_intersect_tile_generic内分配、使用、死亡没有任何调用者读取它返回的键数组raster_bwd.v_screen直到反向传播才存在下一次前向就消失。两者永远不会同时存活所以可以共享同一块分配。实现上src/core/PoolSlots.h 中的POOL_ALIAS_TABLE就是全部声明每行一个缓冲区注明其字节在哪个PoolPhase内有效。DevicePool从单一 arena里用 bump 分配器切块pool_begin_phase()重置游标——arena 的代价是最大的那个阶段而不是所有阶段之和。art_gallery 三次配对实测--cap-max 15000000别名关闭别名开启pool scratchMiB6594 / 6537 / 65445972 / 6078 / 6022GPU 执行每 10 步ms6256 / 5762 / 59235611 / 5942 / 6005平均省下535 MiB8.2%显存时间零感知——bump 分配只是一次指针加法。省下的正是完整的raster_bwd.v_screenintersect 阶段是两者中更大的它决定了 arena 大小梯度缓冲区搭车免费。16 位打包 AABB可见性包围盒减半proj.aabb从每可见对 16 字节降到8 字节每条边 16 位两条边塞进一个 uint32src/shaders/aabb16.hCUDA 与 Vulkan 两个实现分别在 src/core/AabbQuant.cuh 和 src/backend/vulkan/shaders/aabb16.slang。art_gallery 上 231 MiB → 116 MiB且非打包 [C, N] 包围盒查看器和网格化路径用同步减半。几个精妙的设计取舍边是 [0, 图像尺寸] 的均匀划分而不是整数像素。投影已经会把包围盒夹进画面整数像素看似诱人但会把亚像素级 splat 向上取整成整像素——而中小分辨率画面正是被浪费高位会存在的地方恰恰是 splat 恰好只有 1 像素大的地方。步长为 extent/65535608 宽时 0.009 px6000 宽时 0.09 px。min 边向下取整、max 边向上取整解码后的盒子永远包含浮点盒splat 可以多占一个 tile 但绝不少占且顺序保持这个盒子空吗反向传播的剔除判断变成对打包半字的直接比较无需缩放。4 GiB 规则与 2³¹ 上限看不见的 GPU 内存陷阱有两个无声失败的坑值得了解单个缓冲区 4 GiB 上限shader 通过base[i]索引无法越过 4 GiB——驱动会把OpPtrAccessChain的元素偏移折叠成 32 位索引回绕到缓冲区开头静默损坏无报错、无 fault。正确做法是显式构造字节地址即 src/backend/vulkan/shaders/int64_compat.slang 中的elem_at()。所有长度跟随n_isects或nnz的缓冲区都必须走它。没有它的实测代价isect_ids在 5.37 亿个交点处越过 4 GiBmandeltorus 7680×7680 约 1300 万 splatPSNR 从 21.7 跌到 16.0步速慢 17 倍且无任何报错。int32 上限要按 64 位校验int32前缀和为负并不够——在 91 GB 显存的设备上总和超过 2³² 会回绕成一个看起来合理的正数缓冲区按它分配随后是 ~6 W 功耗、无内存流量的 GPU 死循环。所以 src/kernels/tile/IntersectTile.cuh 中的intersect_tile_count自己累加精确总和每个工作组一次InterlockedAdd构造低字进位主机端在扫描前检查这个 64 位值写趟还把窗口夹到真实分配大小内数错也撒不出去。实战指南显存不够时先看哪里 结合以上机制遇到大场景 OOM 时可以这样排查先开SS_PROFILE1看 VRAM 报告的分桶明细——splat x img 桶里哪个缓冲区随n_isects增长最快一目了然。控制--cap-max每图可见 splat 上限。它直接压住nnz屏幕行、AABB、交点列表随之缩小。拆分场景超大规模重建可用 Partition 功能GUI 数据集界面或spirula partition split/merge见 docs/notes/scene-partition.md分块训练再合并。高/低分辨率为何敏感排序代价随n_isects缩放而 gather 代价随nnz缩放4K 画面下不同优化的性价比会反转——所以官方建议任何取舍都先测量再相信。SS_POOL_ALIAS0可整体关闭 arena 别名只改内存布局既是 A/B 杠杆也是逃生舱。延伸阅读源码与文档索引完整设计笔记含被否决方案与实测数据docs/notes/vram-splat-x-img.md缓冲区总表与 VRAM 分桶定义src/core/PoolSlots.h位掩码几何常数src/shaders/packed_mask.h16 位 AABBsrc/shaders/aabb16.h / src/backend/vulkan/shaders/aabb16.slangsplat-tile 相交与 64 位计数src/kernels/tile/IntersectTile.cuh大缓冲区 64 位寻址src/backend/vulkan/shaders/int64_compat.slang文档索引docs/README.md一句话总结splat x img 是 3DGS 训练中唯一模型 × 数据双重增长的显存类别Spirula Studio 用位掩码压缩8 字节/对 → 0.16、阶段竞技场互斥缓冲共享 arena和 16 位打包 AABB 三板斧在几乎不损失速度的前提下为大场景训练腾出了数百 MiB 的余量——这正是 8GB 显存装下千万高斯的底气所在。【免费下载链接】spirula-studioCross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA.项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?