
去年年底我花了三个晚上才把3D Gaussian Splatting3DGS从环境到出图完整跑通。第一晚卡在CUDA和PyTorch版本对不上第二晚栽在COLMAP死活不输出稀疏点云第三晚才真正让训练跑起来。这个过程让我意识到3DGS作为一个视觉算法它的门槛其实不在算法理解而在工具链的版本匹配和工程细节上。简单说3DGS是一种基于显式高斯点云的新视角合成方法。你给它一组照片或一段视频它先通过COLMAP恢复相机位姿和稀疏点云再用可微光栅化器把高斯点渲染成图像通过梯度回传不断调整每个高斯点的位置、颜色、透明度和形状最终得到一个可以实时浏览的3D场景。相比NeRF它的训练和渲染速度都快得多细节还原也更好是目前3D重建和渲染方向绕不开的参考实现。但代价是你要编译CUDA扩展、处理COLMAP依赖、对齐PyTorch和CUDA版本。这篇文章不重复官方README按我实际踩坑的顺序把从零到跑通Demo、再到用自己的数据完整训练的过程讲一遍。适合准备入坑3D重建方向的学生以及想在项目里快速评估3DGS效果的工程师。1. 跑通3DGS前先搞清楚它依赖哪些东西1.1 3DGS的核心链路与NeRF的本质差异3DGS的全称是3D Gaussian Splatting核心思路是用成千上万个三维高斯分布也就是一个个椭圆状的光斑来表示场景。每个高斯点有自己独立的中心位置、协方差矩阵决定形状、颜色、透明度。渲染时这些点按照深度排序后投影到图像平面通过泼溅splatting的方式累加颜色得到最终的像素值。这个思路跟NeRF完全不同。NeRF是用一个神经网络隐式存储场景的密度和颜色查询一条射线上几十个采样点才能得到一个像素的颜色所以训练和渲染都慢。3DGS把场景显式存储为点云集合渲染时每个像素只需要聚合周围的高斯点速度快到能实时。也正因为是显式表示训练时可以直接对每个高斯点做梯度更新不需要隐式网络的前向反向收敛速度比NeRF快一个数量级。理解了这条链路你就能明白为什么环境配置比普通深度学习项目麻烦训练和渲染依赖一个自定义的CUDA光栅化器这个光栅化器不是pip install就能装好的需要本地编译。整个项目的依赖可以分成三块深度学习框架PyTorch、CUDA扩展diff-gaussian-rasterization和simple-knn、数据预处理工具COLMAP。1.2 硬件和软件的前置清单在动手之前先核对一下手里的机器。官方的建议配置是NVIDIA显卡因为光栅化器用了CUDAA卡暂时不在支持范围内。显存的话官方默认配置训练一个30000步的模型大约需要6GB以上显存才比较舒服。我用一张8GB的卡跑一个1700帧的数据集Batch Size默认最后实际占用在5GB左右勉强够用。如果是4090或者A5000这种级别的卡整个训练过程会快很多。软件层面需要准备的东西我列一个表这是我实测可用的组合也是社区里反馈最稳的一套组件建议版本说明Windows / Linux均可官方主要是Linux环境Windows也能跑就是编译时要装Visual StudioPython3.8 ~ 3.10官方推荐3.83.10实测也没问题3.11以上部分依赖容易翻车CUDA Toolkit11.6 以上12.x 也可与PyTorch对应不用装太新PyTorch1.13.1 或 2.0.0必须用与CUDA匹配的安装命令COLMAP3.8训练前恢复相机位姿必备Visual Studio仅Windows2019 / 2022编译CUDA扩展需要MSVC编译器和Windows SDK1.3 版本匹配才是环境配置的主线很多第一次跑3DGS的人最后死在编译阶段原因不是代码有问题而是PyTorch的CUDA版本和本机安装的CUDA Toolkit版本不一致。这里要搞清楚一个概念PyTorch自带了它依赖的CUDA runtime你执行torch.version.cuda看到的是PyTorch内置的CUDA版本它不要求你系统里装有同样版本的CUDA Toolkit。但是编译CUDA扩展时编译器调用的是系统PATH里的nvcc这个来自你单独安装的CUDA Toolkit。如果两者大版本不一致编译出来的扩展运行起来就会报版本不匹配的错误。所以我个人实践下来的建议是先确定PyTorch想要的CUDA版本再安装对应版本的CUDA Toolkit。比如装PyTorch 1.13.1配上CUDA 11.7那就装CUDA Toolkit 11.7保证nvcc版本和PyTorch期望一致。这是整个环境配置里最影响成败的一环后面踩坑排查会专门讲。2. 环境搭建操作从Anaconda到PyTorch和CUDA2.1 创建虚拟环境并把Python版本钉死我习惯用Anaconda管理深度学习环境原因很简单独立性强一个项目一套环境不会把系统Python弄乱。3DGS这种项目依赖比较多而且依赖之间有版本约束放在虚拟环境里最稳妥。conda create -n gaussian python3.8 -y conda activate gaussian这里我的个人建议是Python版本直接选3.8不要选3.11或者3.12。原因不是3.8功能多而是3DGS源码里涉及的一些依赖——比如plyfile、imageio、tqdm在3.8下兼容性最好社区报错最少的也是3.8。虽然3.10实测也能跑但没必要跟版本较劲。2.2 PyTorch安装命令行里的版本玄机创建完环境后安装PyTorch。这一步千万不要用pip install torch的默认命令那样装的是CPU版本后面编译和运行都会出问题。正确做法是先想清楚你要的CUDA版本然后从PyTorch官网复制对应的安装命令。我这里以CUDA 11.7为例pip install torch1.13.1cu117 torchvision0.14.1cu117 --extra-index-url https://download.pytorch.org/whl/cu117如果机器网络状况一般可以把--extra-index-url换成国内镜像但要注意镜像可能没有cu117这种带本地版本的包。我遇到过镜像源只同步了CPU版本装上以后跑起来慢到怀疑人生用torch.cuda.is_available()一查返回False才发现问题。安装完成后立即验证python -c import torch; print(torch.__version__); print(torch.cuda.is_available())这一步必须输出True。如果输出了False不要继续往下走先把PyTorch和CUDA的关系理清楚再说。2.3 CUDA Toolkit的安装与nvcc验证PyTorch自带的CUDA runtime解决了运行时的计算问题但编译CUDA扩展时还需要完整的编译工具链。所以系统里还要装一个与PyTorch大版本一致的CUDA Toolkit。去NVIDIA官网下载对应版本的安装包。Windows下安装时要注意如果你只是编译用不需要覆盖显卡驱动安装时驱动组件可以去掉只留CUDA组件。Linux下如果已经有NVIDIA驱动用runfile方式安装时也不要勾选驱动项否则可能把现有驱动覆盖掉导致分辨率异常。装完验证编译工具是否可用nvcc --version我踩过的一个坑是nvcc命令找不到。原因是CUDA Toolkit安装后不会自动加入PATHWindows需要手动把C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.7\bin加进环境变量Linux需要在~/.bashrc里加export PATH/usr/local/cuda-11.7/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda-11.7/lib64:$LD_LIBRARY_PATH加完执行source ~/.bashrc。2.4 VSCode里接入虚拟环境环境配好后开发调试用VSCode很顺手。装好Python扩展后按CtrlShiftP输入Python: Select Interpreter选择gaussian环境路径里会带conda的envs。这样在VSCode的终端里运行python就直接用的是虚拟环境的Python。这里有个细节VSCode选择解释器之后如果你新开一个终端它默认会激活对应的conda环境。但如果你的终端是普通PowerShell或bash可能需要手动conda activate gaussian。我一般直接把conda activate gaussian加到VSCode的终端初始化命令里或者在sittings.json里加一行python.terminal.activateEnvironment: true省得每次手动激活。其实VSCode在这里最大的价值是调试模式。编译和运行遇到的问题可以用它的调试功能打断点查看错误堆栈比在终端里干瞪眼高效太多。特别是后面如果改了源码调试定位会省很多时间。3. 源码获取与CUDA扩展编译最劝退的一关3.1 克隆仓库注意子模块不能漏官方仓库是graphdeco-inria/gaussian-splatting它用了两个Git子模块diff-gaussian-rasterization可微光栅化器和simple-knn快速K近邻。如果直接用普通的git clone这两个子模块是空目录后面编译会直接失败。正确做法是加--recursive参数git clone --recursive https://github.com/graphdeco-inria/gaussian-splatting.git cd gaussian-splatting如果之前已经用普通方式克隆了可以用这两条命令补拉子模块git submodule update --init --recursive拿到源码后先看一眼目录结构train.py是训练入口render.py是离线渲染convert.py负责把图像转成COLMAP可用的格式gaussian_renderer和scene目录是核心逻辑submodules目录下是两个需要编译的CUDA扩展。3.2 编译diff-gaussian-rasterization接下来是全程最容易出问题的一步。先安装基础依赖pip install plyfile tqdm imageio imageio-ffmpeg然后编译cd submodules/diff-gaussian-rasterization pip install -e .pip install -e .这个命令会调用setup.py而setup.py会调用CUDA编译器把CUDA源码编译成PyTorch扩展。这里的失败率很高常见的报错要么是找不到nvcc要么是MSVC和CUDA版本不匹配Windows下要么是编译时内存不够Linux下默认并行编译会吃满内存。Windows下编译前务必确认Visual Studio的C桌面开发组件已安装而且打开的是x64 Native Tools Command Prompt for VS 2022或者类似的环境在这个终端里再执行conda activate和pip install。直接用普通的PowerShell去编译经常找不到MSVC路径导致报错。Linux下如果内存不够可以在编译前设置环境变量限制并行度export CMAKE_BUILD_PARALLEL_LEVEL2如果还报错就直接在setup.py里的extra_compile_args后面加-j2减少一次并发的编译单元数量。这个方法土但管用。3.3 simple-knn的编译编译完光栅化器还有一个simple-knn也要装cd ../simple-knn pip install -e .这个包负责在稠密化阶段快速计算每个高斯点的K近邻用来控制点的生长和剪枝。它比光栅化器简单编译一般不会出太大问题。两个扩展都编译成功后继续安装COLMAP。3.4 COLMAP进入3D重建的门票COLMAP是3DGS数据预处理的核心工具负责从一组图像里恢复相机位姿和稀疏点云也就是Structure-from-MotionSfM。没有它训练数据根本没法生成。Windows下直接去COLMAP官网下载预编译的release版本解压后把COLMAP.bat所在的目录加进PATH。Linux下可以用apt install colmap但要注意仓库里的版本可能偏旧。我自己用的是源码编译的COLMAP 3.9功能完整对后续处理更友好。如果不想编译官网也提供Linux的预编译包但部分依赖可能不全遇到问题再单独补。装好后验证一下colmap -h如果输出版本信息说明工具可用了。4. 用自己的数据训练从视频到训练集的完整链路4.1 数据拍摄这一步的质量直接决定重建效果很多人拿到项目后习惯性先跑官方Demo数据集。但Demo跑通后真正开始用自己的数据时拍摄环节就把我坑惨了。当时我用手机绕着桌子边走边拍走了两圈结果COLMAP输出几千张图像但匹配上只有几百张点云稀疏到训练出来一片模糊。后来总结出几个拍摄硬性要求画面纹理要多。纯白墙、纯色桌面这种地方特征点提取不出来COLMAP跟踪会断。光照尽量稳定。不要忽明忽暗不要有窗户强光直射造成的过曝区域。镜头移动要平滑。保持每秒约1-2帧的有效帧率不要剧烈旋转或抖动。场景要封闭式环绕拍摄。所有侧面都要覆盖前后重叠率建议在60%~80%这样相机位姿恢复更稳。我后面用手机拍了一段30秒左右的视频然后用FFmpeg抽帧每2秒抽1帧结合场景复杂度控制在120-300张图像左右。抽完帧后建议快速浏览一遍把模糊帧、运动模糊严重的帧直接删掉省得污染后续重建。4.2 用convert.py做图像格式化官方提供了convert.py脚本它会调用COLMAP自动做特征提取、匹配、稀疏重建并把图像resize到指定尺寸。在项目根目录执行python convert.py -s /path/to/your/images-s指向包含图像的目录。脚本会自动创建images、sparse等子目录COLMAP的处理结果统一放在sparse/0下。这里有个关键参数在脚本里默认设置--resize默认的图像长边是1600像素。如果你的显卡只有8GB显存建议直接把长边降到1200或者1000能显著减少训练时的显存占用和内存压力。我第一次跑8GB卡用了默认1600训练到中途直接OOM改成1200后流畅很多。修改方式是在convert.py里找到--resize参数默认值或者直接传参数覆盖。4.3 COLMAP耗时太长手动并行加速convert.py在图像数量多的时候特征提取和匹配阶段非常耗时。300张图片在普通CPU上可能要跑20-40分钟如果中间报错退出前面的工作量还要重来。我的经验是图像数量超过200张时别用convert.py的自动流程手动分步跑COLMAP。先把图像拷到一个images目录下然后依次执行colmap feature_extractor --database_path database.db --image_path images colmap exhaustive_matcher --database_path database.db mkdir sparse colmap mapper --database_path database.db --image_path images --output_path sparseexhaustive_matcher适合300张以内、场景重叠度高的数据跑得最完整但速度最慢。图像数量再多建议换成vocab_tree_matcher配合词汇树速度提升明显匹配质量也不会差太多。如果你有GPUfeature_extractor阶段可以加--SiftExtraction.use_gpu 1速度能快好几倍。跑完以后用sparse/0作为后续训练输入。4.4 启动训练的常用参数与输出文件数据准备好后训练命令很简单python train.py -s /path/to/dataset -m /path/to/output --iterations 30000-s指向包含images和sparse目录的数据集路径-m指定模型输出目录。训练过程中的关键参数--iterations总迭代步数官方默认30000效果已经很好。想快速看效果可以先跑10000步但质量会差一些。--save_iterations指定额外保存中间模型的迭代点比如--save_iterations 7000 14000 21000方便中途查看进度。--test_iterations设置跑测试集评估的迭代点会计算PSNR、SSIM这些指标。--data_device数据device类型默认是cuda显存紧张可以改成cpu但训练速度会慢不少。训练结束后输出的核心文件在output/point_cloud/iteration_30000/point_cloud.ply这就是最终的高斯点云模型。output目录下还有test目录存放测试视角的渲染结果图和PSNR、SSIM数值。4.5 训练中的显存与GPU利用率问题训练时如果你的卡显存不够大有几点可以调整第一减小images的图像分辨率。COLMAP重建用的分辨率是1600或1200但训练时如果你的卡撑不住可以先用较低分辨率跑通流程。第二--batch_size这个参数在3DGS里不是简单的批大小它控制梯度累积步数默认是1不用随便调。第三如果训练时GPU利用率很低先确认是不是数据加载瓶颈不要在CPU上做太多图像处理。另一个容易踩的坑是训练时的可视化输出很占显存。直接用--skip_train --skip_test跳过每N轮的可视化保存能省不少显存。等训练结束需要看结果时再单独用render.py渲染一张图出来就行。5. 训练结果可视化与点云导出实操5.1 用SIBR Viewer做自由视角浏览训练完成后官方仓库里提供了一套基于不同流的交互式查看器也就是Submodules目录下的SIBR_viewers。它需要单独编译编译方式跟diff-gaussian-rasterization类似依赖CMake和CUDA编译工具链。编译通过后启动查看器SIBR_viewers/build/bin/SIBR_gaussianViewer_app -m /path/to/output启动后你就可以用鼠标拖拽旋转、缩放场景从任意视角查看重建结果。这个查看器本身就是3DGS效果最好的展示方式之一比静态渲染图直观得多。5.2 导出点云配合Blender或MeshLab使用如果你想把3DGS的结果导入到其他三维软件里做二次加工需要先把点云从PLY文件转换出来。训练输出的point_cloud.ply已经是一个带法线、颜色信息的点云绝大多数三维软件都能直接导入。我自己的经验是把这个点云直接作为网格重建的输入在MeshLab里跑一遍Poisson重建能生成一个封闭的三角网格。虽然细节相比3DGS原生的高斯基元表达有损失但胜在可以导出成OBJ或STL方便下游使用。如果你希望保留更多高斯基元的语义信息比如每个点的旋转四元数、缩放、透明度那官方仓库的PLY文件里已经包含了这些属性。用Python读一下from plyfile import PlyData plydata PlyData.read(point_cloud.ply) vertices plydata[vertex] properties vertices.properties这样就可以拿到每个点的坐标、颜色、scale、rot等参数做进一步分析或者二次训练。5.3 怎么判断模型训练得到位很多人跑完训练看着渲染图像觉得差不多就结束了但其实可以通过几个指标快速判断模型有没有过拟合或欠拟合。官方训练过程中会打印PSNR和SSIM。PSNR峰值信噪比在测试集上一般能到24以上SSIM在0.8以上说明重建效果比较理想。但这两个指标的绝对值参考意义一般不同数据集的数值差异很大。我的习惯是关注训练集和测试集之间的指标差如果训练集PSNR非常高测试集却很低多半是过拟合了可以通过减少迭代步数、增加数据量或降低SH度数来缓解。另一个更直观的方式是看训练过程中每轮存下来的渲染图像。如果相邻两张图在视角切换时不连续、出现明显的模糊或撕裂感说明高斯点的分布还不够稠密如果某些视角出现大块的缺失或黑色区域说明那个区域的图像覆盖不足需要回去补拍或者调整COLMAP的重建参数。6. 实测高频报错与解决思路6.1 PyTorch与CUDA版本不匹配导致的运行时错误这类错误通常长这样RuntimeError: CUDA error: no kernel image is available for execution on the device或者是Expected one of cpu, cuda, xpu device type at start of operation, but got cuda出现这类问题的根源就是编译时用的nvcc版本与PyTorch运行时期望的CUDA版本不一致。排查思路很简单先看PyTorch的CUDA版本python -c import torch; print(torch.version.cuda)再去终端执行nvcc --version如果两个大版本不一样重新装对应版本的CUDA Toolkit或者用pip install torchxxxcuXXX重装PyTorch。我建议改PyTorch而不是改CUDA因为PyTorch重装只需要一条pip命令改CUDA Toolkit要装完整套驱动链风险大得多。6.2 Windows编译报错找不到MSVC编译器Windows下编译diff-gaussian-rasterization时最典型的报错是error: command cl.exe failed这说明你的编译环境没有MSVC编译器或者cl.exe不在当前PATH里。解决方式是安装Visual Studio Build Tools然后在开始菜单里打开x64 Native Tools Command Prompt for VS 2022在这个终端的上下文里激活conda环境再执行编译命令。有几次我在普通终端里怎么看都找不到cl.exe换了x64 Native Tools终端后一次就过了。这是Windows下吃配置最多的地方。6.3 训练中途显存溢出OOM训练中弹出CUDA out of memory.老显卡和8GB显存卡最容易遇到。首选方案是降低convert.py里的--resize参数把图像长边从1600降到1200甚至1000。训练阶段的显存占用与渲染分辨率直接相关分辨率降下来显存压力立竿见影。另外训练命令加上--skip_train --skip_test减少可视化开销。如果训练集很大还可以减少--test_iterations的测试频率测试阶段会把整批测试图像同时加载到显存是个很大的显存峰值来源。把测试频率从每1000步调成每5000步能缓解不少峰值压力。6.4 COLMAP处理失败稀疏点云为空convert.py跑完后如果sparse/0目录下没有points3D.bin文件说明COLMAP的稀疏重建失败了。最常见原因是图像质量差或者特征点不足特征匹配阶段没找到足够的同源点。先检查图像里是否有大量模糊、过曝、纯色区域。如果图像本身没问题可以手动分步跑COLMAP并把特征提取的阈值调低一些让系统提取更多特征点colmap feature_extractor --database_path database.db --image_path images --SiftExtraction.max_num_features 8192见过很多人被这一步卡住很久其实COLMAP报错信息里往往已经指出了原因。比如它提示匹配数量过低基本上就是图像质量或重叠率的问题重拍比调参数更有效。6.5 训练过程中loss不降或点云不动这个问题比较隐蔽表现是训练迭代很多次PSNR一直上不去或者输出点云的分布和初始值差不多。通常情况下是学习率设置或密度化阈值的问题。官方默认的超参在大多数场景下表现正常但如果你的数据场景特别大或特别小可以尝试调整--densify_grad_threshold和--densify_until_iter。例如场景非常大点云很稀疏可以把密度化阈值调大一点让系统更积极地产生新点。场景很小、过度稠密导致过拟合就调小阈值或者减少--densify_until_iter。不过这种情况出现的概率不高更多时候是前期数据没做好COLMAP重建出来的初始点云质量太差导致后续优化全部徒劳。所以遇到loss不下先回去检查训练集的稀疏点云在查看器里是否完整而不是盲目调参。6.6 一个实用的兜底办法最小化复现环境或代码层面实在排查不出问题时我习惯用官方提供的train.py跑一个最小规模的场景比如4-8张图做一个几十步的快速训练python train.py -s /path/to/tiny_dataset -m /tmp/test_run --iterations 100如果这个最小流程能跑通说明环境和代码是通的问题出在数据或大型配置上。如果连这个都报错那就是环境问题回到前面几个环节逐一检查版本和路径。这个最小化复现的思路帮我省过无数时间遇到再古怪的问题先用最小的场景把问题边界划清楚再去看日志和源码。3DGS的环境配置和运行本质上就是一场版本对齐和数据质量的博弈。工具链的每一步都有成熟的解法官方的文档也写得清楚但真正让你醍醐灌顶的往往是那些报错信息背后的因果逻辑。希望这篇分享能让你少走几个我走过的弯路。