简介:这份源码包面向希望上手3D Gaussian Splatting(3DGS)三维重建的研究者与开发者,尤其适合在非官方推荐环境下摸索部署的初学者。作者以Python 3.10、CUDA 12.3与PyTorch 2.2.1的组合实测跑通全流程,内容覆盖软件环境配置、依赖库安装、数据集下载与格式转换,并延伸到预训练数据训练、结果查看以及使用自有图片训练等环节,还附带视频抽帧、数据转换等实用技巧与调试优化思路。资源包共3个文件,以inscode工程配置、html页面与gitignore忽略规则为主,压缩后约7KB,体量轻便,便于快速导入与查阅。目前已有229人学习关注,可作为3DGS实践入门的参考起点,帮助读者少走环境配置弯路,顺利推进自己的三维场景重建实验。
1. 3DGS 部署与训练指南:从一张显卡到可复现的 Gaussian Splatting 流程
3D Gaussian Splatting(3DGS)这两年在重建圈子里热度一直没掉,原因很直接:它把 NeRF 那套隐式体积渲染换成了显式高斯基元,训练从小时级压到分钟级,渲染还能实时。但真到自己上手,很多人卡在第一步——环境装不上、CUDA 版本对不上、训练跑起来显存直接爆。这篇笔记不讲论文推导,只讲怎么在一台普通带 NVIDIA 显卡的机器上,把 3DGS 从源码部署到训练出第一个可看的场景,顺带把参数怎么调、坑在哪说清楚。适合已经会 Python、用过 PyTorch,但还没跑通过 3DGS 的从业者;如果你已经在跑但结果糊、显存炸,中间几章的参数和排查也能直接用。
2. 部署前必须想清楚的选型:为什么是 3DGS 而不是 NeRF
2.1 显式高斯基元到底解决了什么问题
NeRF 用 MLP 隐式表达场景,每次渲染都要沿射线采样几十上百个点过网络,训练慢、渲染更慢。3DGS 换了个思路:场景由一堆三维高斯椭球组成,每个高斯有自己的位置、协方差、不透明度和球谐系数。渲染时把这些高斯投影到屏幕空间做 alpha 混合,整个过程是光栅化,GPU 天生擅长。结果是训练几分钟到几十分钟,渲染轻松上 100 FPS。
代价也很明显:显存占用和场景规模强相关。一个中等室内场景动辄几百万个高斯,每个高斯要存几十个浮点数,显存不够直接 OOM。所以选型时要先问自己:显卡显存多大、目标场景多大、要不要做动态或大尺度。显存 12GB 以下建议先拿小物体或单房间练手,别一上来就怼整栋楼。
2.2 环境依赖的版本矩阵与安装顺序
3DGS 官方实现依赖 CUDA 扩展,最麻烦的就是版本对齐。常见做法是 CUDA 11.8 + PyTorch 2.0.x + Python 3.10,这套组合在多数教程和社区反馈里最稳。安装顺序不能乱:先装显卡驱动,再装 CUDA Toolkit,再建 conda 环境装 PyTorch,最后编译 3DGS 的子模块。顺序错了,编译时找不到 nvcc 或 torch 头文件,报错能让你怀疑人生。
# 1. 确认驱动和 CUDA 版本(驱动版本要 >= CUDA 要求) nvidia-smi # 2. 创建独立环境,Python 3.10 兼容性最好 conda create -n gs3d python=3.10 -y conda activate gs3d # 3. 装 PyTorch,注意 cu118 对应 CUDA 11.8 pip install torch==2.0.1 torchvision==0.15.2 --index-url https://download.pytorch.org/whl/cu118 # 4. 装编译工具和依赖 pip install plyfile tqdm opencv-python conda install -c conda-forge cudatoolkit-dev=11.8 -y逻辑说明:第一步用 nvidia-smi 看驱动支持的最高 CUDA 版本,别超。第二步独立环境避免污染。第三步 PyTorch 的 cu118 轮子自带对应 CUDA runtime,但编译扩展还需要完整 Toolkit,所以第四步用 conda 补 cudatoolkit-dev。参数上,torch 2.0.1 和 torchvision 0.15.2 是配对版本,别混搭。
2.3 拉取源码与编译子模块
拿到源码后,重点编译两个 CUDA 扩展:diff-gaussian-rasterization 和 simple-knn。这两个是渲染和初始化高斯的底层,编译失败基本等于部署失败。
# 进入项目根目录后,逐个编译子模块 pip install submodules/diff-gaussian-rasterization pip install submodules/simple-knn # 验证是否编译成功 python -c "from diff_gaussian_rasterization import GaussianRasterizationSettings; print('ok')"逻辑说明:pip install 本地目录会触发 setup.py 编译 CUDA 代码。如果报 nvcc 找不到,检查 CUDA_HOME 环境变量是否指向 Toolkit 路径。如果报架构不匹配,在 setup.py 里确认 compute capability 是否覆盖你的显卡(比如 30 系是 8.6,40 系是 8.9)。编译通过后那条验证命令能 import 就说明底层通了。
3. 数据准备与训练启动:从图片到第一个高斯模型
3.1 输入数据的组织与 COLMAP 位姿估计
3DGS 训练需要每张图片的相机内参和外参,标准做法是用 COLMAP 做 SfM。图片要求:同一场景多角度拍摄,重叠度 60% 以上,避免运动模糊和纯反光面。目录结构一般长这样:
scene/ input/ # 原始图片 distorted/ # 去畸变后的图片和 COLMAP 结果跑 COLMAP 可以用官方提供的 convert.py 脚本自动处理,也可以手动跑 feature extractor、matcher、mapper。手动跑更可控,但参数多。常见做法是先用自动脚本跑通,再针对失败场景调。
# 自动转换:去畸变 + 跑 COLMAP + 整理成 3DGS 需要的格式 python convert.py -s scene/ # 如果图片本身无畸变,加 --skip_distortion 省时间 python convert.py -s scene/ --skip_distortion逻辑说明:convert.py 内部依次调用 COLMAP 的 feature_extractor、exhaustive_matcher、mapper、image_undistorter。参数 -s 指定场景根目录。--skip_distortion 适合手机或已校正相机拍的图,跳过去畸变能省不少时间。跑完后 distorted/sparse/0 下会有 cameras.bin、images.bin、points3D.bin,这就是训练要的位姿和稀疏点。
3.2 训练命令与关键参数逐个拆
训练入口是 train.py,核心参数不多,但每个都影响结果和显存。
python train.py -s scene/ -m output/exp1 \ --iterations 30000 \ --resolution 1600 \ --eval \ --densify_grad_threshold 0.0002逻辑说明:-s 是场景路径,-m 是输出模型和日志的目录。--iterations 默认 30000,小场景 7000 也能看,大场景建议 30000 以上。--resolution 控制训练分辨率,显存不够就降到 800 或 1200。--eval 会留出部分图片做测试,方便看指标。--densify_grad_threshold 是致密化阈值,越小高斯越密、显存越高,默认 0.0002,显存紧就调到 0.0004。
参数表:
| 参数 | 默认值 | 作用 | 显存紧时怎么调 |
|---|---|---|---|
| iterations | 30000 | 训练轮数 | 降到 7000~15000 |
| resolution | -1(原图) | 训练分辨率 | 设 800 或 1200 |
| densify_grad_threshold | 0.0002 | 高斯致密化阈值 | 调到 0.0004 |
| densify_until_iter | 15000 | 停止致密化的轮数 | 降到 8000 |
| position_lr_init | 0.00016 | 位置学习率 | 一般不动 |
3.3 训练过程监控与显存控制
训练时终端会打印 loss 和当前高斯数量。高斯数量从几万涨到几百万是正常的,但如果涨到显存上限还没收敛,就要干预。监控用 nvidia-smi 看显存,或者用 wandb 看 loss 曲线。loss 在 0.02 以下通常视觉就不错了,再降收益有限。
# 另开终端实时看显存 watch -n 1 nvidia-smi # 训练日志里关注这两行 # Number of points at iter X: Y -> 高斯数量 # Loss: Z -> 当前损失逻辑说明:watch 每秒刷新显存,方便在 OOM 前手动 Ctrl+C。高斯数量增长过快通常是 densify_grad_threshold 太小或场景纹理太复杂。如果显存到 90% 还在涨,可以中途停掉,用 --densify_until_iter 限制致密化轮数重跑。
4. 避坑与排查:3DGS 部署训练里最容易翻车的五件事
4.1 编译报错 nvcc not found
现象:pip install 子模块时提示找不到 nvcc 或 CUDA_HOME 未设置。原因:只装了 PyTorch 的 CUDA runtime,没装完整 Toolkit,或者环境变量没导出。解决:conda install cudatoolkit-dev 后,export CUDA_HOME=$CONDA_PREFIX,再重新编译。注意 conda 装的 Toolkit 路径和系统路径可能冲突,优先用 conda 的。
4.2 训练一开始就 OOM
现象:刚跑几百轮显存就满,进程被 kill。原因:分辨率太高、图片太多、densify 太激进。解决:先把 --resolution 降到 800,--densify_grad_threshold 提到 0.0004,--densify_until_iter 降到 8000。如果还不行,检查是不是图片本身分辨率过大,可以预先缩放。
4.3 COLMAP 跑失败或位姿错乱
现象:convert.py 中途报错,或者训练出来场景扭曲、重影。原因:图片重叠不够、纯色墙面太多、反光或运动模糊。解决:补拍重叠度高的图片,避开纯白墙和镜面。如果 COLMAP 匹配失败,可以换 sequential_matcher 并加 --vocab_tree 做回环。位姿错乱时检查 distorted/sparse 下的点云是否和图片对得上。
4.4 训练 loss 不降或结果糊
现象:loss 卡在 0.1 以上,渲染出来一团糊。原因:学习率不对、致密化不够、位姿不准。解决:确认 position_lr_init 没被改乱,densify_grad_threshold 别设太大。如果位姿来自 COLMAP 且明显偏移,先修位姿再训练。另外,曝光不一致的图片要先做曝光补偿。
4.5 渲染时高斯闪烁或空洞
现象:新视角渲染有闪烁、拉丝或空洞。原因:高斯数量不足、致密化过早停止、或者训练视角覆盖不够。解决:增加 iterations 和 densify_until_iter,补拍侧视角图片。如果只是轻微闪烁,可以在渲染时调高 resolution 或做后处理滤波。
5. 进阶技巧:把 3DGS 用到实际项目里的几个习惯
5.1 用低分辨率快速验证再全量训练
我一般会先用 --resolution 800 和 --iterations 7000 跑一版,确认位姿和场景没问题,再上全分辨率 30000 轮。这样省时间,也避免全量跑完才发现数据有问题。验证版看三点:高斯数量是否合理增长、loss 是否稳定下降、测试视角是否结构正确。
5.2 显存不够时的分块与降采样策略
显存实在紧张,可以把场景分块训练再合并,或者对图片降采样。分块要注意块间重叠,否则接缝处高斯会断裂。降采样用 OpenCV 或 PIL 批量缩放到长边 1600 以内,通常视觉损失可接受。另一个技巧是冻结部分高斯,只训练新增区域,适合大场景增量重建。
5.3 导出与查看:ply 文件和查看器
训练完在 output/exp1/point_cloud/iteration_30000/ 下有 point_cloud.ply,这就是高斯模型。可以用官方查看器或第三方工具打开。导出时注意 ply 的字段顺序,不同工具对属性命名敏感。如果要嵌入自己的渲染管线,直接读 ply 里的 xyz、f_dc、f_rest、opacity、scale、rot 字段即可。
| 字段 | 含义 | 维度 |
|---|---|---|
| xyz | 高斯中心位置 | 3 |
| f_dc | 球谐直流分量(颜色) | 3 |
| f_rest | 球谐高阶分量 | 45 |
| opacity | 不透明度 | 1 |
| scale | 缩放 | 3 |
| rot | 旋转四元数 | 4 |
5.4 一个我踩过的坑:别在训练中途改参数
有次训练到一半觉得高斯太多,手动改了 densify_grad_threshold 想省显存,结果模型直接崩了,渲染全是噪点。后来才明白,致密化策略和优化器状态是耦合的,中途改参数等于把优化轨迹打断。正确做法是停掉重跑,或者一开始就把参数设保守。这个习惯帮我省了很多后悔药:任何训练参数要么一开始定好,要么重跑,别中途动。
希望帮到你。
本文还有配套的精品资源,点击获取