ARTICLE DETAIL

资讯详情

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

Ubuntu 22.04源码编译CUDA版COLMAP:从显卡架构到加速实战

Ubuntu 22.04源码编译CUDA版COLMAP:从显卡架构到加速实战 我第一次在Ubuntu 22.04上认真折腾带CUDA支持的Colmap编译是因为apt版本在特征提取阶段实在太慢了。当时接了一个几百张图片的三维重建小项目COLMAP一跑CPU直接打满一张图要卡好几秒整批跑完基本要等到天荒地老。翻了日志才发现apt源里的COLMAP压根没开CUDASIFT提取和后面的稠密重建全程在CPU上硬扛。后来我重新从源码编译了一遍把显卡架构、驱动、CUDA、依赖库全部对齐速度直接上了一个量级。这篇文章就是那次的完整记录从显卡架构查询到最终的编译参数设置该避的坑一个不落。1. 为什么apt装好的Colmap总是与CUDA无缘1.1 apt版本落后的真实原因Ubuntu 22.04的软件源里确实有COLMAP直接sudo apt install colmap就能装上但从三维重建的实际使用效果来看这个版本有两个明显的短板。第一个短板是CUDA支持默认关闭。Debian系仓库在打包这种依赖NVIDIA闭源生态的软件时通常会选择不带CUDA的编译路径因为仓库维护者没法假设每个用户机器上都装了NVIDIA驱动和CUDA Toolkit。这导致apt版的COLMAP虽然能跑但SIFT特征提取、PatchMatch Stereo稠密重建这些核心环节全部回落到CPU实现。对于小图集、算法验证来说还能忍一旦遇到几百张甚至上千张照片的重建任务时间成本就完全失控了。第二个短板是版本滞后。GitHub仓库里COLMAP的main分支和release tag不断在修bug、加新功能但Ubuntu仓库同步这些更新往往要等很长时间。你可能照着官方文档操作时发现某个参数在apt版本里根本不存在或者某些重建场景下行为跟官方描述不一致。源码编译能直接解决这两个问题CUDA开关自己控制代码版本自己选。1.2 源码编译对实际项目的价值我自己编译完后的体感非常直接特征提取阶段原本一张4000x3000的图CPU要跑好几秒GPU模式下基本是几百毫秒的量级图片量越大差距越明显。稠密重建里的PatchMatch Stereo更夸张GPU加速后能快十倍以上。做大规模场景重建、倾斜摄影数据、考古数字化这类项目这种速度差异已经不是“体验更好”而是“能不能按时交付”的区别。所以如果你只是拿COLMAP跑个十几张图的demoapt版本顺便用一下没问题但只要你打算认真做重建项目或者要研究SfM/MVS算法本身源码编译基本是绕不开的一步。下面我按完整的链路来讲先查显卡架构再装驱动和CUDA然后准备依赖库最后编译COLMAP并验证。2. 显卡架构与计算能力动手编译前必须先确认的事编译带CUDA支持的COLMAP时CMake必须知道目标显卡的计算能力compute capability也就是我们常说的显卡架构。如果这个值不对编译出来的程序即使能装好运行时会直接给你报no kernel image is available之类的错误。所以第一步不是急着装依赖而是把你的显卡架构搞清楚。2.1 三条命令快速定位显卡最简单的查询方式是依赖已经装好的驱动。在终端执行nvidia-smi --query-gpuname,compute_cap --formatcsv正常情况下会输出类似这样的结果name, compute_cap NVIDIA GeForce RTX 3090, 8.6第一列是显卡型号第二列就是计算能力。有了这个值后面CMake配置时要填的CMAKE_CUDA_ARCHITECTURES参数就直接有了答案。RTX 3090填86RTX 4090填89A100填80。如果驱动还没装nvidia-smi命令不存在那就先通过硬件信息确认显卡型号lspci | grep -i vga sudo lshw -C display看到一个显卡型号后再去NVIDIA官网找对应的计算能力。官网有个专门的CUDA GPUs页面列出了从老到新所有NVIDIA GPU的Compute Capability。也可以装好驱动或者CUDA Toolkit之后用CUDA自带的deviceQuery示例程序来查/usr/local/cuda/extras/demo_suite/deviceQuery输出末尾会有CUDA Capability Major/Minor version number这样的字段直接显示你的计算能力。2.2 计算能力、架构代号与CUDA版本的对应关系NVIDIA显卡的计算能力格式是X.YX代表主架构代次Y代表同代内的细分版本。编译CUDA代码时这个值直接对应到sm_86、sm_89这样的架构标识。下面是我整理的一份常见对照表架构代号计算能力代表显卡建议CUDA版本Turing7.5RTX 20系列、GTX 16系列CUDA 11.x / 12.x均可Ampere8.0A100CUDA 11.x / 12.x均可Ampere8.6RTX 30系列CUDA 11.x / 12.x均可Ada Lovelace8.9RTX 40系列CUDA 11.8以上 / 12.xHopper9.0H100CUDA 12.x这里有个容易忽略的点如果你手里的卡比较老比如GT 730这种Kepler架构计算能力只有3.5那我建议不要装最新的CUDA 12。新版CUDA已经放弃了对一些老架构的支持老显卡配新工具链容易踩到“编译能过但运行时报kernel image错误”的坑。老显卡老老实实用CUDA 11.8反而平稳。2.3 选CUDA版本时还要考虑什么显卡架构只是选型的一个维度。如果你还要在COLMAP之外跑深度学习框架比如PyTorch、TensorFlow最好先确认这些框架的官方wheel绑定的是哪个CUDA版本。找一个交集让COLMAP和你的深度学习环境共用同一套CUDA能省掉很多环境切换的麻烦。我的建议很简单Ubuntu 22.04加30系或40系显卡CUDA 12.1或11.8都行老显卡就选11.8。COLMAP本身对CUDA版本不算挑剔只要Ceres Solver版本匹配基本不会卡在CUDA版本上。3. 驱动与CUDA工具链的正确安装姿势NVIdia驱动和CUDA Toolkit的顺序必须严格先驱动后CUDA。如果反着来后面装驱动时很容易把CUDA自带的driver组件覆盖掉导致内核模块与驱动版本错位开机进不了图形界面的情况我都见过好几次。3.1 显卡驱动安装Ubuntu 22.04下装驱动最省心的是用ubuntu-drivers工具sudo apt update sudo apt install ubuntu-drivers-common ubuntu-drivers devices这个命令会扫描你的机器并列出可安装的驱动版本通常还会标注推荐项。确认推荐版本后直接安装例如sudo apt install nvidia-driver-535装完重启打开终端执行nvidia-smi如果能看到显卡型号、驱动版本和显存占用信息说明驱动已经正常工作了。有一个场景需要额外注意如果你要用的是数据中心显卡比如A100、H100这种常规的ubuntu-drivers也可能识别但这些卡更稳妥的方式是安装NVIDIA官方提供的驱动runfile。家用游戏卡和工作站卡则优先走apt渠道。3.2 CUDA Toolkit下载与安装CUDA Toolkit的官网下载地址是https://developer.nvidia.com/cuda-toolkit-archive我习惯从archive页面选一个明确的版本而不是点页面上的“最新版”因为“最新版”并不总是最适合你的项目。进入页面后依次选择Linux、x86_64、Ubuntu、22.04、runfile (local)下载到的文件类似cuda_12.1.0_530.30.02_linux.run。下载完成后执行sudo sh cuda_12.1.0_530.30.02_linux.run安装过程会进入一个交互式ncurses界面列出Driver、Toolkit、Samples等组件。重点提醒如果你前面已经用apt装好了驱动这里一定要取消勾选Driver只装Toolkit和Samples。不然在这个界面里默认再装一次driver容易发生驱动版本与内核模块不匹配重启后图形界面起不来。装完配置环境变量echo export PATH/usr/local/cuda/bin:$PATH ~/.bashrc echo export LD_LIBRARY_PATH/usr/local/cuda/lib64:$LD_LIBRARY_PATH ~/.bashrc source ~/.bashrc nvcc -V能看到release 12.1之类的版本信息CUDA工具链就算就绪了。3.3 CUDA runfile的gzip报错排查runfile下载或执行时异常最常见的报错是gzip: stdin: invalid compressed>wget -c https://developer.download.nvidia.com/compute/cuda/12.1.0/local_installers/cuda_12.1.0_530.30.02_linux.run有时候浏览器下载大文件容易中断但浏览器不一定报错所以校验哈希值才是最靠谱的判断方式。3.4 多版本CUDA并存与管理机器上同时存在多个CUDA版本是家常便饭。一个项目要CUDA 11.8另一个要CUDA 12.1完全可以共存。CUDA默认安装路径是/usr/local/cuda-11.8、/usr/local/cuda-12.1这样的独立目录而/usr/local/cuda是一个指向当前默认版本的软链接。切换默认版本时直接改软链接sudo rm -f /usr/local/cuda sudo ln -s /usr/local/cuda-11.8 /usr/local/cuda只要环境变量里配置的是/usr/local/cuda切换后所有工具链都会跟着换。这个方案我用了很久比改环境变量或者用容器隔离都直观。4. 依赖库的版本陷阱编译前就要排掉的雷COLMAP的依赖库很多但真正容易出问题的就那几个。一个是被大家反复吐槽的Ceres Solver版本另一个是OpenCV的编译路径选择。前者容易让编译直接失败后者容易让你在配置阶段陷入无底洞。我分开讲。4.1 用apt一把梭的基础依赖大部分基础依赖其实可以一条apt命令解决sudo apt-get install -y \ git cmake build-essential \ libboost-program-options-dev libboost-filesystem-dev libboost-graph-dev \ libboost-system-dev libboost-test-dev libeigen3-dev libflann-dev \ libfreeimage-dev libmetis-dev libgoogle-glog-dev libgflags-dev \ libsqlite3-dev libglew-dev qtbase5-dev libqt5opengl5-dev \ libcgal-dev libceres-dev这里面包含了Boost、Eigen、FLANN、FreeImage、Metis、glog、gflags、SQLite3、GLEW、Qt、CGAL和Ceres。Ubuntu 22.04仓库里这些库的版本都在COLMAP的基本要求范围内绝大多数人执行完这条命令之后依赖层面的百分之八十问题就解决了。不过要注意这条命令里的libceres-dev是Ubuntu自带的Ceres 1.14下面单独说它的坑。4.2 Ceres Solver版本陷阱Ceres Solver是COLMAP做Bundle Adjustment的核心依赖。Ubuntu 22.04仓库里的libceres-dev版本是1.14.0对老版本的COLMAP来说够用但如果你用的是COLMAP 3.9以上或者main分支的较新代码编译时可能会遇到找不到ceres/covariance.h这类头文件的错误这就是Ceres版本太旧导致的。解决办法是源码编译新版Ceres。先装它依赖的底层库sudo apt install -y libgoogle-glog-dev libgflags-dev libatlas-base-dev libeigen3-dev libsuitesparse-dev然后拉取Ceres源码git clone https://github.com/ceres-solver/ceres-solver.git cd ceres-solver mkdir build cd build cmake -DCMAKE_BUILD_TYPERelease .. make -j$(nproc) sudo make installCeres编译得比较久耐心等。安装完成后系统里就有了较新的Ceres之后编译COLMAP时CMake会优先找到它。这里有一个经验之谈很多人在编译COLMAP时报错最后定位到根源是Ceres旧版本所以建议直接跳过apt版Ceres一开始就走源码编译省得后面返工。4.3 OpenCV和CGAL默认版本够用吗COLMAP的图像读写、特征提取和GUI展示都依赖OpenCV。Ubuntu 22.04的apt源提供OpenCV 4.5.4这个版本对COLMAP来说完全够用。我知道有人会想用自己编译的、带CUDA的OpenCV但我的建议是这一阶段不要叠buff。COLMAP本身已经依赖了CUDA如果OpenCV再带一套CUDA模块CMake配置时可能的组合爆炸会显著增加不确定性。等COLMAP整体编译跑通了再考虑要不要动OpenCV。CGAL在COLMAP里主要用在Delaunay三角化和两面重建相关流程。apt源的4.13版本在Ubuntu 22.04上工作正常不需要特殊处理。其他像FLANN、Metis这类小库只要版本不是特别诡异基本不会成为编译瓶颈。5. COLMAP源码编译关键CMake参数与完整步骤依赖备齐、驱动和CUDA都就绪后就可以编译COLMAP本体了。整个流程不复杂但有两个CMake参数非常容易出错我单独拿出来讲。5.1 获取源码与版本选择git clone https://github.com/colmap/colmap.git cd colmapCOLMAP默认分支是main包含最新开发代码。功能新但偶尔会引入新的依赖要求编译报错率会高一点。如果你想求稳我建议切换到release tag比如git checkout 3.9.1release版本经过社区充分测试对应的依赖和构建说明都比较成熟。第一次编译时选一个release tag跑通整个流程后再去体验main分支这个顺序更合理。5.2 CMake配置中两个最容易错的参数创建build目录并进入mkdir build cd build接下来是核心的CMake配置。第一个关键参数是CMAKE_CUDA_ARCHITECTURES前面查询显卡架构的结果在这里派上用场cmake .. \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_CUDA_ARCHITECTURES86 \ -DCMAKE_INSTALL_PREFIX/usr/local比如RTX 3090的计算能力是8.6就填86RTX 4090是8.9就填89。这里建议填具体数字不要用native之类的关键字因为Ubuntu 22.04自带的CMake 3.22虽然支持一部分架构探测能力但在部分复杂环境下native可能探测不准确填具体数字最靠谱。如果希望编译出的程序能在多个不同架构的显卡上运行也可以指定多个值比如-DCMAKE_CUDA_ARCHITECTURES75;86但代价是编译时间变长、binary体积变大。日常使用中指定本机显卡的架构就够了。第二个容易出问题的参数是CMAKE_CUDA_COMPILER。如果你的CUDA不在默认路径或者机器上有多个CUDA版本CMake可能找不到合适的nvcc。此时显式指定cmake .. \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_CUDA_ARCHITECTURES86 \ -DCMAKE_CUDA_COMPILER/usr/local/cuda/bin/nvcc如果在cmake配置阶段报找不到CUDA先确认nvcc -V能正常输出再把/usr/local/cuda/bin和/usr/local/cuda/lib64写进PATH和LD_LIBRARY_PATH重新打开终端再来一次。5.3 编译安装与验证配置成功后开始编译make -j$(nproc)这里注意一下内存占用。COLMAP编译时C和CUDA文件都会占内存如果编译过程中出现killed或者内存溢出可以把并行度降下来make -j4编译完成后安装sudo make install然后验证COLMAP是否可用colmap -h如果输出帮助信息说明安装成功。如果终端提示找不到colmap检查一下/usr/local/bin是否在PATH中或者直接用/usr/local/bin/colmap -h。6. 编译后的常见错误与CUDA加速效果验证6.1 高频报错对照表编译过程或者运行过程中最常遇到的错误我可以整理成一张表方便你直接对照报错信息或现象常见原因解决思路CMake提示找不到CUDAnvcc不在PATH中配置PATH和LD_LIBRARY_PATH后重新cmakeCMAKE_CUDA_ARCHITECTURES检测为0CMake版本过老或显卡架构识别失败显式指定具体的架构数字如-DCMAKE_CUDA_ARCHITECTURES86编译时找不到Ceres头文件系统Ceres版本过旧源码编译新版Ceres后重新编译COLMAP运行时no kernel image is available编译期架构与运行显卡不匹配确认CMAKE_CUDA_ARCHITECTURES正确后重新编译运行时libcudart.so.12找不到动态库路径未刷新执行sudo ldconfig或确认LD_LIBRARY_PATH包含/usr/local/cuda/lib64编译期间进程被OOM杀死内存不足或并行度太高降低make -j参数或临时增加swap6.2 确认CUDA真正生效很多人在编译完成后不确定CUDA是否真的生效这里给出两个直观的验证方法。方法一看COLMAP的帮助选项colmap feature_extractor --help | grep -i sift如果你看到输出中有--SiftExtraction.use_gpu这类选项说明COLMAP在编译时确实检测到了CUDA并开启了GPU支持。如果没有这个选项或者显示--SiftExtraction.use_gpufalse且无法调节那基本可以断定CUDA路径没生效。方法二实际运行时观察GPU占用。随便找一组图片执行colmap feature_extractor在另一个终端窗口运行nvidia-smi如果能看到一个COLMAP或CUDA相关进程在占用GPU说明GPU确实在参与计算了。这个方法最直观也能直观看到显存占用和利用率。6.3 CPU与GPU效率对比最后聊一下实际的性能差异。不同硬件环境下数据会有波动我这里给一个参考同为SIFT特征提取和匹配CPU模式下4000x3000的图像可能需要数秒GPU模式通常能压到几百毫秒。Dense重建阶段的PatchMatch Stereo差距更夸张GPU加速可能带来十倍以上的提升。我自己测过一组130张航拍图的重建CPU模式特征提取阶段耗时约二十分钟GPU模式只需要两分多钟。这个差距足以让整个项目的交付节奏发生质变。有一点需要说明GPU加速也不是万能的。特征提取时如果图像本身非常小GPU的调度开销可能掩盖加速收益但正常的三维重建任务里图像基本都在千万像素级别GPU的优势非常明显。所以如果你打算长期用COLMAP做正经项目CUDA支持是标配不是可选项。最后分享一点个人体会。COLMAP这类涉及众多第三方依赖的项目“版本对齐”永远是最大的隐性成本。编译前花十分钟把显卡架构、CUDA版本、Ceres版本三个关键点确认清楚比编译中遇到报错再一个个去查要高效得多。建议第一次编译时选择稳定的release tag跑通整个流程后再去尝试main分支或自定义编译选项。如果你装完之后遇到“明明按步骤来了还是报错”的情况优先检查CMake缓存删掉build目录重新配置一次往往比在旧缓存上反复折腾更有效。
返回列表