product

YouTube 点赞数已达 10,000 次,订阅数已达 100 次 | 高品质 | 快速发货

¥ 11.00
获取资源


  前两天看到李飞飞 Worldlabs 新工作Mrable的时候,提到后面想多看一看 3DGS / 重建相关的工作。李飞飞公司发布空间智能模型 Marble,从单张图生成 3D 世界,生成效果如何?对行业有何影响?

  但是知乎搜了一下发现,讲 3DGS 论文原理、改进的不少,我自己上半年也回顾过cuda kernel 源码:重温经典之 3DGS CUDA 源码解析 ,但是另一个常用的gsplat 开源库则基本无人 care。

  官方 arxiv链接:https://arxiv.org/pdf/2409.06765顺便一提,3DGS 虽然也有可训练的模型/高斯参数,但是和常规的深度学习模型、框架都有不小的差别。和 CV/自驾还算有点关系,毕竟也需要涉及坐标系转换、lidar 点云等,24年还有很多人在做自驾感知/端到端和 nerf/3dgs 的结合,但和 LLM / NLP 则是基本毫无关联,跟概率论我觉得关系也不大。如非必要,大模型er 慎重踩这个坑。

  不过如果真的有小白要踩坑,gsplat 的文档和维护其实比gaussian-splatting 要稍微好一些,个人更推荐这个库。

  相比3DGS 论文对应的 gaussian-splatting 库,nerfstudio-projectgsplat 是对官方库做了一些优化,可参考https://docs.gsplat.studio/main/migration/migration_inria.html 的说明。

  (也还有OpenSplat 、gaustudio等不少框架,不过 opensplat 是基于 C++的,gsustudio 我不太了解)

  搜 gsplat 的时候还意外发现这个: 就像最近的NeRF、Gsplat一样。然后再过几年,如果发现生成质量一直上不去,或者算力要求巨高,凉了,那就没啥影响了。如果效果做的特别好,各种控制技术越来越精巧,文字理解越来越到位,不仅没凉反而真的能取代光追渲染器了,有人就会宣称Diffusion Transformer是计算机图形学的奠基技术之一。然后大学图形学课上开始将Sora作为经典案例来讲,有学生实现简化版Sora作为小作业,企业招图形学工程师面试加入Diffusion Transformer相关的考题。作者:Raymond Fei链接:OpenAI 的新视频生成模型 Sora 将对计算机图形学产生什么影响? 。

  从从业者的角度,我是非常期待“世界模型”的应用能广泛一些,无论视频生成还是场景重建,现在发展都有点惨淡。吃肉是大佬的事儿,不过哪怕效果和应用场景能有 LLM 1/4,算法和Infra 的小卡拉米们也有机会喝点汤不是(手动狗头)。俺真不太想换赛道去卷 LLM....

  四元数计算平移旋转第一次接触这玩意是大二做智能车的时候...在单片机解陀螺仪位姿...回忆杀说来就来

  相机坐标系和世界坐标系转换gsplat 还强调其支持超广角畸变和卷帘快门的相机模型(好吧又是一波智能车比赛的回忆杀,自己学的东西是真杂)

  gsplat 提供的高斯球存储压缩功能,文档介绍可以将 1M 的高斯球参数从 236MB 压缩到 16.5MB,仅有 0.5dB 的 PSNR 损失,原理包括量化(Quantization):降低数值精度排序(Sorting):提高压缩效率K-means聚类:专门压缩球谐系数PNG编码:利用图像压缩技术

  https://docs.gsplat.studio/main/apis/rasterization.html 包含了 utils 中的多个操作fully_fused_projection(): 3D→2D投影isect_tiles() :tile相交检测isect_offset_encode() :编码偏移量rasterize_to_pixels() :像素光栅化

  可以参考gsplat论文中的图来理解

  对于初识 3DGS 的同学,这个图对于理解协方差的投影也有些帮助:

  文档列出来的几个公式涉及的知识点:3D高斯参数: μ ∈ ℝ³:3D高斯的中心位置(x, y, z)Σ ∈ ℝ³×³:3D协方差矩阵(描述高斯的形状和方向)c:颜色属性o:不透明度公式 Σ = RSS^T R^T是协方差矩阵的分解: S = diag(s) ∈ ℝ^{3×3}:缩放矩阵,s ∈ ℝ³是缩放向量 (sx, sy, sz),控制高斯在三个轴上的大小R ∈ℝ^{3×3}:旋转矩阵,由四元数 q ∈ ℝ⁴ 表示 (w, x, y, z),控制高斯的方向透视投影的雅可比矩阵J:

  投影过程计算 2D 协方差: Σ' = JWΣ W^T J^T 计算 2D 投影的中心位置:

  2D投影参数: μ' ∈ ℝ²:投影后的2D中心位置Σ' ∈ ℝ^{2×2}:投影后的2D协方差矩阵z:深度值

  通过官方的 examples 可以对 rasterization的输入输出参数和shape 有一个基本概念

  高斯球可以通过多种方式初始化,比如利用点云 SfM 初始化,但其并不像很多深度学习 Model 一样初始化后参数量就 Fix 下来了,在 3DGS 后续的训练中,高斯球的数量还会有变化,即 3DGS 论文中的 ,不同论文/方法会对应不同的更新策略,常规的比如分裂、复制、裁剪。

  gsplat将高斯的密集化和修剪过程抽象为 策略(Strategy),从代码来看包括以下关键过程:: 使用检查参数和优化器的格式是否正确: 初始化策略状态: 反向传播前的回调: 反向传播后的回调

  DefaultStrategy 对应3DGS 论文的默认策略,包括:复制高斯球:触发条件: high image plane gradients and small scales.原理:高梯度 说明该区域重建误差大,需要更多高斯;小尺度:说明是精细结构,不适合分裂(会破坏细节)。所以使用复制而非分裂:保留原有细节结构,在附近增加高斯球密度分裂高斯球:触发条件:high image plane gradients and large scales.原理:大高斯难以精确表示复杂几何,所以通过分离,用多个小高斯更好地拟合局部细节。修剪高斯球:触发条件:low opacity.原理: 低透明度的高斯球对图像贡献小,重置高斯球到低透明度:触发条件:定期触发(对应 reset_every 参数)原理:防止部分高斯球不透明度过早收敛到 1,让不同高斯球重新展开竞争。

  MCMCStrategy 对应另一种常用的方法https://arxiv.org/abs/2404.09591,gsplat 也给出了mcmc 的 demo : https://github.com/nerfstudio-project/gsplat/blob/main/examples/benchmarks/mcmc_4gpus.sh

  https://docs.gsplat.studio/main/apis/utils.html

  提供了更基础的 Python API 操作,以 rasterize_to_pixels 为例,可以直接

  通过 gsplat/__init__.py 可以找到其函数定义在:https://github.com/nerfstudio-project/gsplat/blob/main/gsplat/cuda/_wrapper.py 中,类型检查之后,就是调用 cuda kernel 了,前向和反向对应两个 kernel:fwd 在 https://github.com/nerfstudio-project/gsplat/blob/main/gsplat/cuda/csrc/RasterizeToPixels3DGSFwd.cu#L191 bwd 在 https://github.com/nerfstudio-project/gsplat/blob/main/gsplat/cuda/csrc/RasterizeToPixels3DGSBwd.cu kernel 和原始的 gs 并无多大区别

  参数转换:计算球谐函数,将球谐系数转换为RGB颜色支持可选的mask来跳过部分计算:将四元数和缩放转换为协方差和精度矩阵可选择只计算其中一个(节省计算)支持返回上三角形式(压缩存储)

  projection 相关::将高斯球投影到2D像素空间(支持透视和正交投影)支持多种相机模型:、、、 核心函数,融合了计算协方差、世界到相机空间变换、投影到2D多个操作。支持模式(内存优化)支持(稀疏梯度)自动过滤视锥体外的高斯支持视角相关的不透明度补偿:将高斯从世界坐标系转换到相机坐标系

  tile 相关:将投影到 2D 空间的高斯球映射到与其相交的像素 tile支持排序和分段排序返回每个高斯相交的瓦片数和相交ID:将相交ID编码为偏移量,用于后续的光栅化操作

  光栅化渲染:将高斯光栅化到像素支持背景色和遮罩支持(绝对梯度计算):迭代光栅化可以分批处理高斯(从近到远)返回高斯-像素相交的索引

  运行脚本:

  核心的 rasterize_to_pixels 调用栈如下,从外到内大概过一下

  https://github.com/nerfstudio-project/gsplat/blob/main/examples/simple_trainer.py#L601

  3D 到 2D projection

  

  投影结果解析:

  2. 球谐函数处理

  3. tile 相交检测

  tiles_per_gauss:每个高斯球和多少个 tile 相交(会用于多少个 tile 的渲染,就需要 copy 多少份)比如tiles_per_gauss[0, 5] = 4,表示第 5 个高斯球会用于 4 个图片tiles 的渲染isect_ids : 记录 tile 与 image 关系Shape为 需要参与渲染的高斯球数量(复制之后)如 debug 窗口所示,tiles_per_gauss.sum() = isect_ids.shape[-1]其编码格式为:

  flatten_ids:表示第 i 个记录对应哪个高斯球

  编码 offset 格式,并更新 meat

  4. 光栅到像素

  5. 返回

  trian 循环调用 包括两部分

  更新策略:

  是的,3dgs 的训练从去年开始就发展出了多种并行方式,用来加速训练和减少大场景的显存占用,gsplat 的并行实现来自 On Scaling Up 3D Gaussian Splatting Training ( On Scaling Up 3D Gaussian Splatting Training ) 作者提的 PR:https://github.com/nerfstudio-project/gsplat/pull/253 ,但是gsplat 的实现比Grendel 的开源实现少了像素负载均衡等功能。并行方案的话,稍微有点像大模型里面的 TP + DSP 。高斯球加载到不同的 GPU 上(类似 TP 切模型参数)在 render 前,用 all_to_all / sparse_all_to_all 将高斯球并行转换为像素tile 渲染的并行(类似于 DSP 在多维 Transformer 间维度的转换)在 loss 计算阶段,沿用像素块/图像间的并行。这里简单过一下,如果感兴趣 gs 坑的人多,再展开吧。

  在初始化阶段切分,即中:

  在 https://github.com/nerfstudio-project/gsplat/blob/main/gsplat/rendering.py#L360

  packed 说明可以参考:https://github.com/nerfstudio-project/gsplat/pull/253 和 https://docs.gsplat.studio/main/apis/rasterization.html

  不需要额外计算,全都通信,用的时候再加 mask isect_tiles 和 rasterize_to_pixels 都也会包括 packed 参数

Copyright © All Rights Reserved.