ARTICLE DETAIL

资讯详情

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

3DGS复现全流程:从环境配置到训练避坑的完整指南

3DGS复现全流程:从环境配置到训练避坑的完整指南 简介面向首次接触3D高斯泼溅3D Gaussian Splatting三维重建的零基础新手这份资源是一份基于Ubuntu 20.04.3 LTS与RTX 3080 Ti环境的完整复现记录。文档以真实踩坑过程为主线覆盖环境配置、虚拟环境创建、依赖安装、COLMAP稀疏重建与训练运行各阶段集中整理了新手极易遇到的典型问题更新显卡驱动后黑屏、COLMAP编译报undefined reference、MP4视频无法播放、PNG图像读取异常等并逐条给出排查思路与解决步骤同时保留版本对应关系和命令行示例。资源以1个doc文档形式打包压缩包约96.32MB内含图文并茂的过程记录和多轮排错截图适合边对照边操作。作为一份完成度较高的踩坑复盘可让缺乏经验的学习者避开弯路快速识别同类报错并找到修复路径。目前已有5056人学习下载是入门3DGS复现时非常实用的参考手册。1. 3DGS复现全流程为什么人人说简单你却卡在“准备”这一步3D高斯3DGS的复现全流程说简单是真的简单训练脚本只有一条命令。但说难也真难——我见过太多新手在第一步就放弃了不是死在训练代码上而是死在编译C扩展、死在COLMAP跑不出稀疏点云、死在数据格式不对。这个项目标题的价值就在这里它不是教你背参数而是把一条完整的路走通。这篇文章按顺序讲清楚环境、数据、训练、排错四个环节适合那些想自己复现3DGS、想用自己的照片做三维重建、但还没摸清全链路的人。你会看到哪些步骤必须死磕哪些地方可以灵活绕过。2. 先把环境焊死CUDA、PyTorch与diff-gaussian-rasterization的版本对齐2.1 为什么编译环节劝退了大多数新手大多数新手第一次跑3DGS以为装好PyTorch就能直接跑结果在pip install阶段就开始翻车。3DGS的训练核心不完全是Python它包含一个用CUDA和C写的自定义光栅化模块diff-gaussian-rasterization负责把上百万个高斯原语快速渲染成图像同时完成反向传播。这个模块必须在你自己的环境里重新编译编译要匹配三样东西CUDA Toolkit版本、PyTorch的CUDA版本、以及Visual Studio或GCC。三者的版本任何一对不上编译器就会抛出一堆看似无关的报错。我自己踩过的典型情况是PyTorch是CUDA 11.8编译的系统里却装了CUDA 12.1的Toolkit运行训练时张量能从GPU跑到CPU但自定义算子加载时直接崩溃报CUDA error: no kernel image is available。这种报错属于典型的黑匣子问题你根本想不到是版本错配。所以环境准备的第一步不是急着跑代码而是先把版本对齐这件事焊死否则后面每一步都是玄学。2.2 版本选型和硬件底线的参考组件推荐配置备注GPURTX 3060 12GB 起步显存低于8GB建议缩小图片分辨率NVIDIA驱动最新稳定版525驱动太老会导致CUDA runtime不识别CUDA Toolkit11.8 或 12.1必须和PyTorch编译时的CUDA版本一致PyTorch2.0 / 2.1 对应CUDA 11.8不要用CPU版或太新的2.4Visual StudioWindowsVS2019 或 2022装C桌面开发组件仅Windows需要Linux用gcc 9COLMAP3.8用于生成相机位姿和稀疏点云一个容易被忽略的硬件问题显存不够时新手第一反应是换小模型但3DGS的显存占用主要来自渲染分辨率和点云密度图片分辨率每降一半显存占用能降到原来四分之一。如果你只有8GB显存建议先别用30000次迭代的默认配置先把图片缩到1024px再说。2.3 用最小步骤把环境跑通环境准备推荐顺序是先装驱动和CUDA Toolkit再装PyTorch最后编译子模块。不要反过来。先确认版本没问题再开始下载代码。# 1. 检查显卡驱动和CUDA版本 nvidia-smi nvcc --version # 2. 创建虚拟环境建议Python 3.9避开新版本兼容坑 conda create -n gs python3.9 -y conda activate gs # 3. 安装PyTorch注意cuda版本号要和Toolkit一致 pip install torch2.0.1cu118 torchvision0.15.2cu118 --index-url https://download.pytorch.org/whl/cu118PyTorch安装完成后不要急着装其他依赖先验证一下CUDA到底能不能用import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))这一步如果输出True并显示显卡型号说明深度学习框架层面没问题。之后再去编译diff-gaussian-rasterization和simple-knn这两个是训练和渲染的底层依赖。编译前确认当前终端能直接调用nvccWindows上如果提示找不到命令需要手动把CUDA安装路径加进环境变量。# 编译CUDA扩展项目根目录下执行 cd submodules/diff-gaussian-rasterization pip install -e . cd ../simple-knn pip install -e .这段命令的逻辑是把C/CUDA算子编译成Python可以直接调用的扩展包。如果编译过程出现红色报错不要盲目重装先把报错的最后几行截图或复制下来绝大多数问题都指向CUDA版本不匹配。Linux用户还要注意安装g和cmakemacOS用户不用尝试3DGS的CUDA光栅化在macOS上跑不了。跳过这步的代价我在帮别人排查时见得太多了有人以为自己装了官方代码里要求的全部依赖训练时却报ModuleNotFoundError: No module named diff_gaussian_rasterization。所以我建议编译成功后用一行命令确认你的环境彻底闭环了python -c import diff_gaussian_rasterization; print(OK)看到OK环境这关才算真正过了接下来才轮到数据。这一步虽然繁琐但它是整个流程里唯一需要“拼运气”的环节熬过去后面基本都是一路绿灯。3. 3dgs自己制作数据集手机拍摄、抽帧与COLMAP稀疏重建3.1 拍摄规范和照片数量的关系很多人拿到3DGS第一反应是去下载官方示例数据集跑通了很开心但一旦换成自己拍的数据就各种报错。这就是没理解3DGS训练的前提它需要准确的相机位姿而位姿靠COLMAP从图片里算出来。公开数据集拍照时用的是单反相机、固定分辨率、高重叠度你用手机随手拍一圈视频再抽帧COLMAP很可能匹配不到足够的特征点稀疏重建直接失败。自己制作数据集时我建议遵守几条硬规矩。先说照片数量单个物体或小场景30到80张足够一个房间或大型场景至少100到200张。少于30张COLMAP算位姿的冗余太少了稀疏点云会稀稀拉拉训练出来的模型到处是洞。视频抽帧时帧率不要贪高每秒5到10帧足够抽太多了相邻帧几乎一模一样重叠度过高反而增加匹配时间还可能让BA捆集调整退化。拍摄角度上环绕是基本操作但上下方向也要覆盖到。具体做法是绕着物体走一圈是主循环每走几步俯拍一张、仰拍一张这样三维空间里的特征点分布均匀重建出来的几何不会出现天花板塌陷或地面漂浮。另一个非常关键的点是避免运动模糊手机在暗光环境下很容易拍糊一张糊图可能毁掉相邻多张图的匹配结果。3.2 视频抽帧与图片预处理的操作步骤视频抽帧用FFmpeg是最常见的一套做法一小段一分钟的视频能抽出几百张图。注意抽帧前先把视频裁掉开头结尾的冗余段只保留有效画面能减少后续处理时间。# 安装ffmpeg后执行 mkdir -p images # 从视频中每秒抽取5帧保留原始质量 ffmpeg -i input.mp4 -vf fps5 -q:v 2 images/%04d.jpg # 统一缩放到最短边1200px避免原视频4K导致训练显存爆炸 ffmpeg -i input.mp4 -vf fps5,scale-2:1200 -q:v 2 images/%04d.jpg这段命令里scale-2:1200的意思是高度缩到1200像素宽度按比例自动计算且保持偶数避免后续COLMAP提取特征时因为奇数尺寸报错。-q:v 2控制JPG压缩质量值越小质量越高2到3之间比较合适不要用默认值。iPhone或Android拍摄的视频一般是1920x1080或4K直接用来训练要么显存不够要么训练时间翻倍缩到1200px是个平衡点。抽完帧后打开文件夹看一眼删掉严重过曝、脱焦、重复率过高的帧。这一步靠直觉但效果立竿见影图片质量高COLMAP匹配到的特征点就多后面训练出来的点云密度和细节程度都会上一个台阶。图片数量不够时宁可再拍一段补上也不要硬凑短视频里连续两帧几乎完全相同的情况在特征匹配时相当于把同一张图重复算了两次对相机位姿估计没有正面帮助。3.3 用COLMAP跑稀疏重建并理解它输出了什么3DGS官方代码默认不直接读原始图片而是读COLMAP的SfM结果。所以你的数据必须过一遍COLMAP让它算出一组相机内外参数和一个稀疏点云。COLMAP有图形界面也有命令行为了可复现我建议用命令行方式。# 1. 特征提取对images目录下所有图片做SIFT特征检测 colmap feature_extractor \ --database_path database.db \ --image_path images \ --ImageReader.single_camera 1 # 2. 特征匹配计算所有图片间的特征匹配关系 colmap exhaustive_matcher \ --database_path database.db # 3. 稀疏重建估计相机位姿和3D点云 mkdir -p sparse colmap mapper \ --database_path database.db \ --image_path images \ --output_path sparse三条命令由浅入深对应SfM的三个步骤。single_camera 1的意思是假设所有图片来自同一台相机共用一套内参手机拍摄满足这个条件能显著提高重建稳定性。如果你的照片是用不同手机拍的必须改成0否则内参会互相打架。exhaustive_matcher适合几百张以内的图片量超过500张建议改用sequential_matcher它按图像顺序匹配速度更快但可能漏掉部分远距离匹配。COLMAP跑完之后sparse/0目录下会生成cameras.bin、images.bin、points3D.bin三个文件这就是3DGS训练需要的关键输入。很多新手在这一步看完输出目录是空或者缺文件原因多半是特征点匹配数量太低。COLMAP缺少覆盖到标定目标物比如棋盘格三维重建出几千个点其实很常见。判断成功的底线是points3D.bin对应的点数至少要到两三万如果只有几千点训练出来的效果大概率是残缺的。CAM 模型用 COLMAP 的可视化工具打开sparse/0直接看稀疏点云长什么样会不会有相机位姿明显飞掉的情况。这一步的耐心直接决定后面的训练值不值得跑。4. 跑通3DGS训练全流程数据整理、训练脚本与关键参数4.1 把COLMAP输出整理成官方仓库要求的目录结构环境有了、数据有了下一步就是把数据喂给训练脚本。这里卡住新手最多的是目录结构问题。3DGS官方训练脚本train.py要求数据集按特定路径组织但COLMAP输出的原始路径是扁平的需要手动调整。我不止一次看到有人把sparse/0和images全塞进一个文件夹然后训练脚本报错找不到相机参数。我一般会按下面的结构整理dataset/ ├── images/ # 原始图片与COLMAP输入的图片一致 └── sparse/ └── 0/ ├── cameras.bin ├── images.bin └── points3D.bin这个结构看起来简单但有两个容易踩的细节。第一images里的图片必须和COLMAP处理的是同一批文件不能COLMAP跑完后又往images里加了新照片否则图片数量和位姿数量对不上训练时随机采样会报索引越界。第二cameras.bin文件是自带相机内参的不需要额外写配置文件因为3DGS的加载逻辑就是从COLMAP的二进制文件里读参数的。4.2 启动训练的最小命令与参数说明数据整理好后训练本身的命令极其简单这也是3DGS让新手觉得神奇的地方。一条命令跑起来剩下的是看日志。python train.py \ -s /path/to/dataset \ -m /path/to/output \ --iterations 30000 \ --test_iterations 7000 15000 30000 \ --save_iterations 7000 15000 30000这段命令的四个参数分别对应数据路径、输出目录、训练轮数、测试和存档点。-s指向上一节整理好的数据集根目录-m是训练产物保存位置训练中每迭代一定次数会把点云和相机参数存到该目录--iterations是总训练轮数默认30000官方论文用的就是这个数。前面的--test_iterations 7000 15000 30000表示在7000、15000、30000轮时各跑一次测试并输出评估指标方便看你训练的体验不是每个脚本版本都有这个参数没有也不影响。我强烈建议第一次训练不要动任何超参数先跑通一轮拿到正常loss曲线再谈优化。3DGS之所以对新手友好是因为默认参数在绝大多数常规场景下都能收敛。你只需要保证图片清晰、位姿准确、显存不爆剩下的交给默认值。4.3 训练过程中最重要的三个超参数新手在跑通第一次训练后会忍不住去调参。这时只推荐先动三个超参数迭代次数、密度化阈值、最大球谐阶数。参数默认值作用调参方向--iterations30000总训练轮数显存吃紧时降到20000追求细节时提到40000--densify_grad_threshold0.0002控制高斯原语分裂/克隆的梯度阈值调大到0.001让模型更稠密调小到0.0001抑制漂浮物--sh_degree3球谐阶数控制视角相关颜色表达显存不足或场景简单时降到2densify_grad_threshold尤其值得注意。3DGS训练过程中会不断把高斯原语分裂成更多小原语让每个原语更贴合几何细节但设置过低会让点云激增显存和训练时间直线上升。如果训练结束发现漂浮物太多常见做法是调高这个阈值从0.0002改到0.0008能显著减少那些游离在半空中的小点。sh_degree则是球谐阶数它决定了从不同角度观察颜色是否会随视角变化对于有光泽的表面比如汽车、反光金属阶数越高越真实但参数体量和显存开销也越大。场景中反光不严重时降到2训练速度能提升不少。# 一个显存紧张、画面有漂浮物时的典型调整方案 python train.py \ -s /path/to/dataset \ -m /path/to/output \ --iterations 20000 \ --densify_grad_threshold 0.0005 \ --sh_degree 2 \ --test_iterations 5000 20000另一个重要概念是loss构成。3DGS的损失函数是L1损失加上一项基于SSIM的感知损失系数大约为0.2。L1负责逐像素颜色接近SSIM负责保持局部结构相似。训练初期的loss下降非常快从几百掉到十几就是一两千轮的事之后缓慢下降。如果loss卡着不动多数情况不是参数没调好而是数据本身有问题——这是下一章重点。5. 3DGS复现避坑实录新手最容易踩的 6 个坑与排查顺序5.1 CUDA与PyTorch版本不匹配编译期间爆红报错现象编译diff-gaussian-rasterization时出现nvcc fatal : Unsupported gpu architecture compute_89或者编译完训练时报CUDA error: no kernel image is available。原因显卡太新比如RTX 40系但CUDA Toolkit装旧了编译器不认识新GPU的架构另一个极端是CUDA装得太新但PyTorch是旧版编译的运行库不匹配。这两个问题表面报错不同根子都是版本错配。解决先执行nvcc --version和python -c import torch; print(torch.version.cuda)对比两边版本强制对齐。RTX 30系用CUDA 11.8 PyTorch 2.0.1是经过大量验证的组合RTX 40系建议CUDA 12.1 PyTorch 2.1以上。对齐版本后删掉build目录重新编译一次不要在原目录上直接重装。5.2 COLMAP稀疏重建失败点云数量只有几千点现象COLMAP命令跑完points3D.bin文件很小训练出来的模型全是洞或者干脆训练时报找不到3D点云。原因照片质量差、重叠度不够或拍摄时光线剧烈变化导致SIFT特征匹配不到。另一种常见原因是抽帧频率太高相邻帧几乎相同特征匹配虽然成功但相机位姿约束不够强。解决回看拍摄环节。先把图片数量降到30-60张保证相邻图片有明显视角差再用COLMAP面板可视化匹配结果看有没有图片完全没匹配上。COLMAP的mapper命令加--Mapper.ba_global_function_tolerance 1e-6能提升部分复杂场景的收敛稳定性但核心还是重拍重拍。5.3 8GB显存训练OOM程序直接闪退现象训练刚开始几百轮显存占用拉满程序报CUDA out of memory。原因显存不够是结果根因通常是输入图片分辨率太高比如4K原图直接喂进去或者默认点云密度上升太快。解决优先降图片分辨率到800-1000px而不是换配置。改images文件夹里的图片尺寸后要重新跑一遍COLMAP因为相机参数是跟着图片走的。其次降迭代次数到15000-20000最后才考虑把--sh_degree降到2。这三个先后顺序不要颠倒降分辨率是性价比最高的操作。5.4 训练loss不降渲染画面一片模糊或全是噪点现象loss曲线在初始值附近抖动训练过程不下降渲染出来是一个形状模糊的白团或者满天稀疏噪点。原因多数是初始化点云质量太差。COLMAP产生的稀疏点云只有几万点且在场景中分布不均高斯原语初始化时缺失了大量采样点也可能图片太少CAMPOSE 没覆盖到某些视角模型无法在这几个方向收敛。解决先回看COLMAP的稀疏点云可视化结果确认每个角度都有点覆盖。如果分布不均补拍照片重跑。如果点云没问题把--iterations提到40000试一次给模型更多时间把模糊区域分裂细化。记住一个血泪经验训练效果的好坏七成在数据三成在参数。5.5 视频抽帧出来的图片缺EXIFCOLMAP报焦距错误现象COLMAP的feature_extractor跑完提示大量图片没有正确焦距甚至直接报Error: invalid EXIF data。原因视频抽帧生成的JPG经常丢失EXIF信息COLMAP读不到焦距只能用默认值或你指定的值代替误差大了位姿就飘。解决最大的教训是不要用视频抽帧做主要数据源能拍照就别拍视频。如果只有视频使用前可以给所有图片统一写入一个固定的焦距。用COLMAP命令指定--ImageReader.single_camera 1能缓解这个问题因为所有图都共用同一套内参相对位姿的正确率会高不少。最保险还是拍照片手机直接拍几百张照片的EXIF信息是完整的后面省心得多。5.6 渲染完出现漂浮物和重影画面不干净现象训练正常收敛loss也降了但视角转到特定方向时出现半透明的团块悬在空中或者边缘部分有重影。原因数据拍到相机视锥之外的区域或者背景中反复出现运动物体造成的重影。高斯原语把不应该存在的区域当成场景的一部分表示训练后期又没能剔除干净。解决拍摄时尽量让背景静止车辆、行人、飘动的树叶都会变成漂浮物。训练后处理时把--densify_grad_threshold调大到0.0005-0.001减少过度分裂同时把--iterations加长给剪枝暴露。若漂浮物已经生成官方仓库里有一个prune操作可以手动删除那些不透明度低的高斯原语。这一步是玄学成分最多的需要多试几组参数。6. 复现不是终点用真实指标评估模型并把成果导出成视频跑通一次训练只是开始验证模型质量才是真正检验你理解没理解的关键。我见过太多人看到loss降了就以为大功告成那其实是自我安慰。看一个模型到底好不好最直接的指标有三个PSNR、SSIM、LPIPS。PSNR侧重逐像素还原精度越高越好SSIM看结构相似度接近1最优LPIPS是感知指标越低代表人类感觉越接近。官方仓库的render.py和metrics.py是验证的基本工具。训练结束后执行render.py生成所有测试视角的渲染图再用metrics.py算出三组指标。我自己的习惯是先看PSNR是否超过22dB低于这个数字说明训练质量堪忧需要回来查数据问题SSIM低于0.85也要警惕。还有一个更直观的方法把测试集渲染图和真实照片并排放大看细节看纹理边缘有没有糊、高光区有没有颜色断层这比任何数值都诚实。模型确认没问题后导出成果是大多数人想做的事。常见做法是把训练好的模型用SIBR实时查看器打开360度旋转看整体效果这是最直观的验证手段。如果要让更多人看到成果可以把渲染结果合成为视频下面这组命令是常规套路# 用render.py生成序列帧按预设相机轨迹渲染 python render.py \ -m /path/to/output \ --skip_train \ --skip_test \ --render_path trajectory # 再用ffmpeg把序列帧合成MP4按30fpsH.264编码 ffmpeg -framerate 30 \ -i /path/to/output/trajectory/%05d.png \ -c:v libx264 -crf 18 -pix_fmt yuv420p output.mp4前一条命令会读取训练时保存的相机位姿生成一组平滑移动的视角画面后一条命令把这些画面变成视频。-crf 18是质量参数数值越小越清晰视频体积也越大。我自己的教训是早于7000轮存档的模型不值得导出太早了高斯原语还在快速增长渲染结果会出现大量闪烁和撕裂。最后的建议如果复现到这一步还有余力去自己拍摄一个复杂场景——有反射、有细碎结构、有遮挡关系——用它把训练、评估、导出重新走一遍。这个过程会逼你理解每个参数存在的理由。一套流程走完你才真正有了自己的3DGS手艺希望帮到你。本文还有配套的精品资源点击获取
返回列表