3DGS(3D Gaussian Splatting)这套东西最近有多火不用我多说,辐射场重建基本快被它带成标配了。但很多朋友第一次接触时会卡在同一个地方,不是训练逻辑看不懂,也不是数据准备不会做,而是编译diff-gaussian-rasterization这个子模块的时候,屏幕上蹦出一堆看着眼熟却又无从下手的报错。我在好几个项目里帮人排查过这个问题,群里也几乎每天有人问“这个报错有人遇到过吗”,所以这次干脆把常见坑位和完整排错思路整理出来。
这篇东西适合正在装或者正准备装 3DGS 环境的人,尤其是那些在 Linux 上已经能跑通 PyTorch、但一编译 CUDA 扩展就头大的朋友。也适合 Windows 用户,虽然官方对 Windows 的支持不算一等一,但确实有人用 RTX 显卡在 Windows 上硬装成功了,我把对应的注意事项也写进来。你不需要一开始就懂 CUDA 内部机制,只要照着步骤走,再理解几个关键检查点,大概率能把自己从报错里捞出来。
1. 先搞懂这个包是干什么的,再决定怎么装
1.1 它是3DGS里的核心CUDA光栅化模块
diff-gaussian-rasterization是 3DGS 官方实现里的 CUDA 光栅化模块,负责把成千上万个高斯椭球实时投影到图像平面上。名字里的diff表示它是可微的,训练时需要向前渲染出图像、向后回传梯度,这两个过程都在这个模块里完成。换句话说,没有它,整个 3DGS 训练流程就跑不起来。
这个模块不是普通的 Python 库,它需要被编译成 PyTorch 的 C++/CUDA 扩展。你在命令行里执行安装时,本质上是让setup.py调用 nvcc 和 C++ 编译器,把src目录下的.cu、.cpp文件编译成 PyTorch 可以调用的动态链接库。任何环节的版本不匹配、环境变量缺失、编译器不兼容,都会以各种报错的形式拦在门口。
1.2 为什么偏偏它最容易装挂
我在实际项目里见过太多类似的情况:CUDA 装好了、PyTorch 能正常import、显卡驱动也正常,但一编译扩展就失败。原因在于,编译过程比普通 Python 包多了一条完整依赖链。
这条链大致是这样的:PyTorch 本身是带着自己编译时用的 CUDA runtime 版本发布的,而你的 nvcc 来自独立安装的 CUDA Toolkit。两者版本最好兼容。再往下,.cu文件里的很多头文件来自 CUDA Toolkit 自带的 CUB、Thrust 等库。最后一步,C++ 编译器也不能太老或者太新,否则要么语法不支持,要么和 nvcc 之间配合出问题。
这条链路里只要有一环脱节,报错方式千奇百怪。最常见的不是“缺少某个包”这种直白提示,而是编译到一半突然输出一堆模板实例化错误,或者直接给你一句ninja: build stopped: subcommand failed。新手看到这种信息基本就懵了,但只要你理解了链路结构,排查方向就清晰很多:先检查 nvcc 与 PyTorch 的 CUDA 版本对应关系,再检查编译器可用性,最后看编译日志里真正抛错的那一行。
2. 装之前必须确认的三件事
2.1 CUDA版本:nvcc 和 PyTorch 内置 CUDA 的匹配关系
这是最核心的一环,也是大部分人踩坑的起点。diff-gaussian-rasterization编译时,会用到 PyTorch 提供的编译参数,例如-gencode里带有 PyTorch 所基于的 CUDA 版本信息,同时你的 nvcc 也带有自己版本的编译行为。
如果你的 PyTorch 是 cu118 版本,但系统里默认 nvcc 是 CUDA 12.1,编译时可能会出现运行时兼容问题,或者干脆在编译阶段因为某个 CUDA 头文件路径变了而失败。我见过很多次fatal error: cuda_runtime.h: No such file or directory,就是因为在没有 CUDA_HOME 的情况下,nvcc 找不到头文件。
要确认版本,先看 PyTorch 自带 CUDA 版本:
python -c "import torch; print(torch.version.cuda)"再看 nvcc 版本:
nvcc --version如果不是同一个大版本,建议先统一。怎么统一?最省事的方式是直接用 conda 安装匹配的 PyTorch,例如 CUDA 11.8 就装 cu118 对应的 torch 版本。同时系统级 CUDA Toolkit 也尽量装 11.8,两个版本一致能少掉不少幺蛾子。
2.2 编译器环境:Linux 用 gcc/g++,Windows 用 MSVC
diff-gaussian-rasterization编译时需要 C++ 编译器。Linux 上通常是 gcc/g++,Windows 上则是 Visual Studio 的 MSVC。
很多人在这一步吃的亏是:gcc 版本过新。比如 Ubuntu 24.04 自带 gcc 13,用它去编译一些老一点的 CUDA 扩展,经常出现模板相关报错。CUDA Toolkit 11.8 官方支持的最高 gcc 版本是 11,gcc 12、13 虽然也能用,但偶尔会在 C++ 标准库头文件解析上出问题。
如果你遇到莫名其妙的编译错误,可以用gcc --version看看版本,然后在编译时临时降低版本:
export CC=/usr/bin/gcc-11 export CXX=/usr/bin/g++-11Windows 上则是另一套体验。你需要安装 Visual Studio 2019 或 2022,并在安装时勾选“使用 C++ 的桌面开发”工作负载。否则编译时会提示找不到cl.exe,或者出现一堆 MSB 错误。这里有个小技巧,用“x64 Native Tools Command Prompt for VS 2022”来跑编译命令,环境变量会自动配置好。
2.3 官方子模块有没有拉全
如果你是从 3DGS 项目仓库而不是单独 clone 这个子模块,有个非常容易忽略的点:diff-gaussian-rasterization在仓库里是以 git submodule 形式存在的。
很多人直接git clone https://github.com/graphdeco-inria/gaussian-splatting.git后,发现submodules目录是空的,或者里面只有一个空壳文件夹。这时候直接去 pip install 必败无疑。
必须单独拉取子模块:
git submodule update --init --recursive这个操作会在submodules目录下真正拉取 diff-gaussian-rasterization 以及另外两个依赖扩展的代码。拉完之后再检查下目录里有没有setup.py和src目录,有才算完整。
3. 一套经过验证的安装流程(Ubuntu + CUDA 11.8 为例)
3.1 创建干净环境并安装匹配的 PyTorch
我建议你在一个全新的 conda 环境里操作,避免不同项目之间的依赖互相干扰。以 Ubuntu + CUDA 11.8 为例,下面是完整流程。
conda create -n 3dgs python=3.10 -y conda activate 3dgs pip install torch==2.0.1 torchvision==0.15.2 torchaudio==2.0.2 --index-url https://download.pytorch.org/whl/cu118这里选 Python 3.10 是兼容性非常稳的选择,PyTorch 2.0.1 + cu118 是官方 3DGS 仓库测试较多的组合。如果你用 PyTorch 2.1 或更高版本,大部分情况下也能跑通,但没必要在环境搭建阶段给自己增加变量。
装完 PyTorch 后,立刻验证一次:
import torch print(torch.cuda.is_available()) print(torch.version.cuda)能输出True和11.8,说明 PyTorch 和 GPU 驱动这一层没问题。
3.2 编译安装 diff-gaussian-rasterization
接下来进入子模块目录安装。我的习惯是先把CUDA_HOME指到实际安装路径,避免系统找不到 nvcc。用which nvcc找到路径后,再设置环境变量。
export CUDA_HOME=/usr/local/cuda-11.8 export PATH=/usr/local/cuda-11.8/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-11.8/lib64:$LD_LIBRARY_PATH然后执行:
cd submodules/diff-gaussian-rasterization pip install .如果顺利,你会看到 nvcc 开始编译大量.cu文件,最后生成.so动态库。整个过程大概几分钟,取决于 CPU 性能。编译期间不要开太多重型程序,内存不够也会导致进程被 kill。
安装完成后,测试导入:
import diff_gaussian_rasterization print(diff_gaussian_rasterization.__file__)能打印出模块路径,说明安装成功。
3.3 验证是否成功
除了导入模块,我还会额外确认一下函数接口是否完整。diff_gaussian_rasterization对外暴露的核心 API 是GaussianRasterizer,以及它依赖的GaussianRasterizationSettings和GaussianRasterizationContext。
from diff_gaussian_rasterization import GaussianRasterizer from diff_gaussian_rasterization import GaussianRasterizationSettings, GaussianRasterizationContext print("All imports OK")如果你的应用场景是跑完整 3DGS 训练流程,那还要把另外两个子模块也装好。分别是simple-knn和submodules/fused-ssim等,但核心渲染依赖就是diff-gaussian-rasterization负责的,这个模块通过后,主流程就能往下走了。
4. 实战排错:五个高频报错的完整排查记录
4.1 “subcommand failed”身后往往有真正的错误
ninja: build stopped: subcommand failed是我见过出现频率最高的报错。很多人一看到这个就直接截个图发群里,其实这只是一个结果提示,真正的原因在它上面几百行的编译日志里。
怎么定位?关键是把编译输出重新完整跑一遍,不要用pip install的默认隐藏模式。可以这样:
pip install . -v加了-v之后,完整编译命令和中间输出都会打出来。你往上翻,找第一个出现error:的位置。很多时候真正的错误是这一句:
/usr/include/c++/x/bits/std_function.h:xxx: error: static assertion failed或者:
error: identifier "AT_CHECK" is undefined如果看到AT_CHECK is undefined,这是因为新版 PyTorch 把AT_CHECK改成了TORCH_CHECK,而子模块代码还停留在老版本。解决办法很简单,打开源码,把报错文件里的AT_CHECK全局替换成TORCH_CHECK。我遇到过两次这种情况,替换后就能继续编译。
这就是排查的通用思路:不要盯着ninja: build stopped本身,往上翻日志,找到具体那个.cpp或.cu文件里的错误,再对症下药。
4.2 nvcc 找不到 / CUDA_HOME 没设
如果你看到这样一串报错:
nvcc: command not found或者:
fatal error: cuda_runtime.h: No such file or directory基本就是 CUDA Toolkit 环境变量没配置好,或者你的PATH里根本没有 nvcc。
先确认 Toolkit 是否真的装了:
ls /usr/local/ | grep cuda如果你发现只有/usr/local/cuda而没有具体版本目录,那说明 Toolkit 可能没装全,或者只有驱动。这个模块编译必须依赖完整的 CUDA Toolkit,光有显卡驱动是不够的。驱动负责运行,Toolkit 负责编译。
如果确认 Toolkit 存在,但 nvcc 还是找不到,那就在命令行里强制指定:
export CUDA_HOME=/usr/local/cuda-11.8 export PATH=/usr/local/cuda-11.8/bin:$PATH这里有个实际操作心得:不要把 CUDA_HOME 设置成/usr/local/cuda这种软链接路径,因为有些版本的 setup.py 会解析出奇怪的结果。直接指向具体版本目录最可靠。
4.3 缺少 CUB / GLIBC 报错
编译过程中如果出现类似:
fatal error: cub/device/device_scan.cuh: No such file or directory或者:
/usr/include/c++/x/cstdlib:xx: std::abort has not been declared前者是缺少 CUB 库,CUB 是 CUDA 的并行原语库,在高版本 CUDA 里已经集成进 CUDA Toolkit,但一些老版本的源码里会单独引用。
解决办法很简单,检查你的 CUDA 版本。如果你的 CUDA 大于等于 11.0,CUB 就在 Toolkit 里。如果是 10.x 或者更早,你需要手动 clone CUB 并把它放到/usr/local/cuda/include下。
后者std::abort这类报错通常是 gcc 版本太高导致的。我前面提过,降低 C++ 编译器版本到 gcc-11 或 g++-11 就能解决。
4.4 Windows 下的 MSVC 与 cl.exe 问题
Windows 上安装 3DGS 的体验确实要折腾一些,但我见过不少人成功了,所以只要按对姿势来,也没那么吓人。
典型报错之一是:
error: Microsoft Visual C++ 14.0 or greater is required这说明你缺 MSVC 编译工具链。要解决,你需要安装 Visual Studio Build Tools 或完整版 Visual Studio,并确保勾选了“使用 C++ 的桌面开发”。安装完成后,重启终端,让环境变量生效。
另一个典型问题是在普通 CMD 里编译时找不到cl.exe。这是因为 MSVC 的环境变量没有加载。解决办法是打开“x64 Native Tools Command Prompt for VS 2022”,在里面激活 conda 环境,然后再执行安装命令。这个顺序很重要,先加载 MSVC 环境,再激活 conda,否则编译时还是会报错。
还有一点 Windows 专属的坑:PyTorch 的 CUDA 版本架构和显卡算力匹配。比如使用旧显卡时,TORCH_CUDA_ARCH_LIST没设置好,会报no kernel image is available for execution on the device。解决办法是在安装前指定:
set TORCH_CUDA_ARCH_LIST=7.5具体值取决于你的显卡算力,可在 NVIDIA 官网查到。RTX 30 系列填8.6,RTX 40 系列填8.9。这个环境变量不仅 Windows 上有效,Linux 上也一样,可以避免编译出来的扩展不支持自己的显卡。
4.5 运行时才爆的 cudaErrorInsufficientDriver / undefined symbol
编译通过不代表万事大吉,有时候导入模块时会蹦出运行时错误。我遇到过比较典型的两类:
一类是:
CUDA error: no kernel image is available for execution on the device这基本是算力不匹配。编译时没有针对你的显卡架构生成对应的 SASS 或 PTX,运行时自然无法执行。解决方式就是设置TORCH_CUDA_ARCH_LIST后重新编译。
另一类是:
ImportError: undefined symbol: _ZN2at4detail...这种符号找不到,通常是因为 PyTorch 版本和编译时不一致。比如你编译时用的是 PyTorch 2.0.1,后来又把 PyTorch 升级到了 2.1,扩展模块就会因为依赖的老符号不存在而导入失败。
解决办法很直接:保持 PyTorch 版本不变,重新编译这个模块。这也是为什么我一直强调在干净环境里操作,避免版本漂移。
5. 常见问题速查表与避坑心得
5.1 报错现象、可能原因、解决方向速查表
我把遇到过和听同行提到过的高频问题整理成了一张表,方便你快速定位。
| 报错现象 | 可能原因 | 解决方向 |
|---|---|---|
ninja: build stopped: subcommand failed | 编译日志中隐藏实际错误 | 加-v重跑,定位首个error: |
nvcc: command not found | PATH 未配置或 Toolkit 未装 | 设置 CUDA_HOME 并加入 PATH |
fatal error: cuda_runtime.h | 头文件路径未找到 | 检查 CUDA_HOME 指向具体版本目录 |
error: identifier "AT_CHECK" is undefined | 源码老 API 不兼容新 PyTorch | 将AT_CHECK替换为TORCH_CHECK |
fatal error: cub/device/device_scan.cuh | 缺少 CUB 库或路径不对 | 确认 CUDA Toolkit 已安装 CUB |
Microsoft Visual C++ 14.0 or greater is required | 缺少 MSVC 编译工具 | 安装 VS Build Tools,勾选 C++ 桌面开发 |
cl.exe not found | MSVC 环境变量未加载 | 在 x64 Native Tools 命令行中操作 |
导入时undefined symbol | PyTorch 版本和编译时不匹配 | 固定 PyTorch 版本后重新编译 |
运行时no kernel image | 显卡架构未包含在编译目标里 | 设置TORCH_CUDA_ARCH_LIST后重编 |
粗体行都是我在真实场景里见过的,不是网上抄来的。这张表你可以直接截图收藏,遇事不决先对一遍。
5.2 几个别人不会写在文档里的实操技巧
最后分享几个实际项目中摸索出来的经验,能帮你少走很多弯路。
第一,编译时内存不够导致进程被 kill。diff-gaussian-rasterization的编译峰值内存不低,尤其是大显存机器上并行编译时。如果你看到Killed字样,先用free -h查内存,留出足够余量。可以临时限制并行度,避免内存爆炸:
export MAX_JOBS=4这个变量会被 ninja 识别,降低并行编译任务数。
第二,pip 的缓存有时候会捣乱。如果你改了源码或环境变量后重新安装,发现还是报同样的错,可能是 pip 缓存了旧包。清理一下:
pip install . --no-cache-dir第三,编译日志保存下来。我每次帮人排查问题,第一件事就是让他们把完整日志保存成文件,而不是只截最后几行:
pip install . -v 2>&1 | tee build.log这样下次再报错,不用重复跑一遍,直接在 log 文件里搜error就能定位。
第四,如果你是在 WSL 里编译,CUDA 相关环境跟原生 Ubuntu 有区别。WSL2 里通常不需要单独装驱动,但要确保 Toolkit 安装的是 WSL 版本,否则 nvcc 运行会出问题。
第五,如果实在反复编译失败,可以试试直接拉取官方预编译的 wheel。注意这不是官方推荐路径,一些社区成员会发布针对特定 PyTorch/CUDA 版本的预编译包,但来源要自己甄别。我更喜欢自己编译,至少出了问题能知道具体是哪一步挂的。
安装这类 CUDA 扩展其实没有太多玄学,核心就是让 nvcc、PyTorch、C++ 编译器三者处在一个相对和谐的状态里。版本保守一点,环境干净一点,日志看得全一点,大部分报错都是可以解决的。希望这篇能帮你少熬几个夜。