ARTICLE DETAIL

资讯详情

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

Ubuntu 22.04 源码编译安装带 CUDA 的 Colmap 完整指南

Ubuntu 22.04 源码编译安装带 CUDA 的 Colmap 完整指南 搞三维重建的朋友应该都绕不开 Colmap 这个开源神器尤其是做运动恢复结构SfM、多视角立体视觉MVS或者给 NeRF、3D Gaussian Splatting 准备数据的时候基本都要靠它。但这里有个很容易踩的坑在 Ubuntu 22.04 上直接用 apt 安装的 Colmap往往是 CPU 版本特征提取、稠密重建这些环节跑起来简直慢到怀疑人生。所以很多人最后都要走一遍带 CUDA 支持的源码编译安装路线这篇文章就针对“Ubuntu 22.04 Colmap CUDA 编译安装”这套组合把全流程、显卡架构查询方法、以及我实际踩过的坑一次讲透。适合刚上手三维重建、被 CPU 版 Colmap 折磨过的同学也适合需要在服务器上从头部署整套环境的开发者参考。1. 编译前的整体思路与方案选型1.1 为什么必须带 CUDA 编译 Colmap先说结论如果你只是处理几十张小图CPU 版 Colmap 咬咬牙还能忍一旦到了几百上千张图像的数据集CPU 版和 GPU 版的差距就不是“快一点”而是“数量级碾压”。原因在于 Colmap 内部几个核心模块都重度依赖 CUDA特征提取阶段SIFT 特征检测的 GPU 实现比 CPU 实现快很多尤其是在高分辨率图像上特征匹配阶段暴力匹配和几何验证都有 CUDA kernel 加速稠密重建Delaunay 三角化、像素级深度估计更是 CUDA 的主场CPU 版在这里基本属于灾难级别。而 apt 仓库里的 Colmap 包问题不只是没开启 CUDA还在于版本往往滞后。Ubuntu 22.04 自带的 Colmap 是 3.7 左右的老版本SfM 管线和一些接口跟现在的上游代码差了不少。所以无论从性能还是功能角度看源码编译带 CUDA 的版本都是更稳的选择。1.2 源码编译 vs 预编译包与容器方案有人会问直接拉 Docker 镜像不香吗确实香Colmap 官方提供了打包好的 Docker 镜像开箱即用。但容器方案有两个痛点第一GPU 透传环境如果没有提前配好 NVIDIA Container Toolkit光是折腾--gpus all就够喝一壶第二做研究的时候经常需要改 Colmap 源码、加调试输出、或者链接自己修改过的第三方库这时候容器镜像的封闭性就成了阻力。源码编译看起来麻烦实际上一套流程跑通之后后续的二次开发、版本切换都会顺畅很多。而且源码编译可以针对你自己的显卡架构做代码生成优化运行效率比通用预编译包还高一点。这篇文章走的是源码编译路线目标很明确。1.3 整体流程的编排逻辑我习惯把整个编译安装拆成四个阶段每阶段都有明确出口方便排查问题系统环境准备更新软件源、安装基础工具链build-essential、git、cmake、ninjaCUDA 环境部署确认显卡驱动正常、安装 CUDA Toolkit、配置环境变量Colmap 依赖安装把所有第三方库通过 apt 装齐Colmap 源码编译拉取源码、CMake 配置、编译、安装、验证。为什么把 CUDA 环境放在依赖安装之前因为 Colmap 的 CMake 配置阶段会同时检测 CUDA 和第三方库如果 CUDA 没配好后面检测到一堆红色警告你会分不清到底是 CUDA 的问题还是库的问题。先搞定 CUDA再装库遇到问题定位起来就清楚多了。2. 环境准备基础工具链与 CUDA 部署2.1 基础工具链安装先说系统层面的准备。官方建议在干净系统上进行但如果你已经装了一堆开发环境也没关系只要注意别把系统自带的 Python 或者 CMake 搞坏就行。打开终端先更新软件源并升级sudo apt update sudo apt upgrade -y然后安装编译必需的工具链sudo apt install -y build-essential git cmake ninja-build pkg-config这里重点说下构建工具的选择。Colmap 官方文档推荐用 Ninja 而不是 Make原因是 Ninja 在增量编译时速度更快、并发控制也更合理。Ubuntu 22.04 自带的 CMake 是 3.22 版本Colmap 要求的 CMake 最低版本是 3.16所以系统自带的 CMake 完全够用不需要额外折腾新版。构建过程中我们还需要一些辅助工具建议顺手装上sudo apt install -y ccache yasmccache 能缓存编译中间产物如果你后面反复改 CMake 参数、重新编译能省下不少时间尤其是 Colmap 这种代码量级的项目全量编译动辄十几分钟ccache 的加速效果立竿见影。2.2 CUDA Toolkit 安装方式对比CUDA Toolkit 的安装方式主要有三种deb网络安装、deb本地安装、runfile安装。我实测下来给个对比安装方式优点缺点推荐指数deb 网络安装依赖自动处理、升级方便需要网络稳定安装过程不可控四星deb 本地安装离线可用、依赖自动处理包体积大需要提前下载三星半runfile 安装路径完全可控、可自定义组件不自动处理依赖环境变量需要手动配四星如果你追求省心直接走 deb 网络安装是最稳妥的。在 NVIDIA 官网选择对应系统架构和版本会得到两条安装命令wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb sudo dpkg -i cuda-keyring_1.1-1_all.deb sudo apt update sudo apt install -y cuda注意这个命令安装的是cuda这个 meta 包会把所有 CUDA 组件都装上。如果你只想装 toolkit 而不需要额外的驱动或者文档可以只装cuda-toolkit-12-3这种带版本号的包。2.3 runfile 方式安装细节与 gzip 报错处理虽然 deb 方式省心但 runfile 方式在特定场景下更好用比如你需要把 CUDA 装到非标准路径、或者想跳过 NVIDIA 驱动只装 Toolkit。Colmap 编译其实只需要 nvcc 编译器和 CUDA runtime 库驱动你早就用nvidia-driver装好了所以 runfile 的“跳过驱动”选项反而成了优势。runfile 安装的关键步骤wget https://developer.download.nvidia.com/compute/cuda/12.3.0/local_installers/cuda_12.3.0_545.23.08_linux.run sudo sh cuda_12.3.0_545.23.08_linux.run执行后会出现一个文本交互界面按CtrlC跳过协议阅读或者直接按q然后选择你需要的组件。重点来了如果你的驱动已经装好了第一个选项[X] Driver记得把X取消掉只保留 CUDA Toolkit 相关的组件。这一步很多人会踩一个坑下载的 runfile 大概率会报gzip: stdin: invalid compressed>export PATH/usr/local/cuda/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda/lib64:$LD_LIBRARY_PATH然后source ~/.bashrc再执行nvcc --version就能看到 CUDA 版本信息了。2.4 显卡驱动检查与常见版本匹配问题在装 CUDA 之前一定要确认你的 NVIDIA 驱动是正常的。执行nvidia-smi能看到显卡型号、驱动版本、以及右上角的 CUDA Version 就说明驱动没问题。注意这个 CUDA Version 表示当前驱动支持的最高 CUDA 版本不代表你已经装了 CUDA Toolkit两个概念很多人会混淆。驱动版本决定了你能装哪个版本的 CUDA Toolkit例如驱动版本如果停留在 535那 CUDA 12.2 及以下的 Toolkit 都兼容高于这个版本的就需要先升级驱动。如果你发现自己还没装 NVIDIA 驱动最简单的安装方式是sudo apt install -y nvidia-driver-535 sudo rebootUbuntu 22.04 用nvidia-driver-535这个版本在我的多台机器上验证过稳定性没问题。装完后建议用nvidia-smi验证一下 GPU 是否被正确识别。对于 WSL2 用户情况更简单WSL2 里不需要在 Linux 侧装驱动直接使用 Windows 宿主机的驱动即可。你只需要确认 Windows 端驱动是新的然后在 WSL2 里正常安装 CUDA Toolkit 就行Colmap 编译流程和原生 Ubuntu 没有任何区别。3. 显卡架构查询如何获取正确的 compute capability3.1 CUDA 架构算力到底是个啥CUDA 的“架构”全称是 Compute Capability中文一般叫“计算能力”或者“算力”用一个形如8.6、8.9的编号表示。这个编号很重要因为它直接决定了编译出来的 GPU 代码能在哪些显卡上跑。可以这么理解CUDA 编译的产物不只是通用的机器码还包含针对特定 GPU 架构的 SASS 指令。如果你的编译目标和实际显卡架构不匹配程序运行时会报no kernel image is available的错误。常见的显卡架构对应关系显卡系列架构代号Compute CapabilityRTX 4090 / 4080 / 4070 / 4060Ada Lovelace8.9RTX 3090 / 3080 / 3070 / 3060Ampere8.6A100Ampere8.0RTX 2080 Ti / 2070 / 2060Turing7.5GTX 1080 / 1070 / 1060Pascal6.1V100Volta7.0Tesla T4Turing7.5拿 4060 Ti 来说它属于 Ada Lovelace 架构Compute Capability 是 8.9对应 CUDA 版本需要 11.8 以上才支持。很多用 4060 Ti 的同学问“4060ti 支持哪个 CUDA 版本”本质就是算力和 CUDA Toolkit 版本之间的兼容关系后面详细讲。3.2 查询显卡算力的三种方法方法一NVIDIA 官方的 CUDA GPU 支持列表。打开官网查对应型号就能看到 Compute Capability这是最权威的途径但页面比较长找起来费时间。方法二写一个小程序跑deviceQuery。CUDA Toolkit 自带的 sample 里有现成的代码不过为了查一个数字去编译 sample 有点小题大做。方法三直接看显卡型号对照表。这也是我平时最常用的方式因为桌面级显卡的算力基本都是固定的记住几组关键数据就行20 系是 7.530 系是 8.640 系是 8.9。如果你拿不准最保险的方法是在 CMake 配置时用native参数让编译器自动检测当前显卡架构这个我们在下一步详细说。3.3 把算力告诉 Colmap 的正确姿势Colmap 的 CMake 配置中与显卡架构相关的变量是CMAKE_CUDA_ARCHITECTURES。这个变量在 CMake 3.18 之后被正式纳入标准Colmap 的 CMake 脚本会读取它来决定 nvcc 编译时生成什么架构的代码。最常见的三种写法# 写法一自动检测当前显卡最省心 -DCMAKE_CUDA_ARCHITECTURESnative # 写法二指定具体算力适合固定部署环境 -DCMAKE_CUDA_ARCHITECTURES89 # 写法三指定多个算力生成的程序可在多款显卡上运行 -DCMAKE_CUDA_ARCHITECTURES75;86;89native的缺点是它只针对当前编译机器上的显卡做优化生成的程序拷贝到别的显卡上可能跑不了。如果你只是自己用native简单粗暴完全没问题如果是给实验室服务器编译建议先查清楚服务器上是什么卡直接用具体算力值设置。关于多架构设置有个性能上的细节值得注意生成的 SASS 代码会包含多份架构相关的二进制程序体积更大加载时间略长。所以如果不是要在不同显卡之间迁移不建议设置太多架构一个就够。4. Colmap 源码编译实操全流程4.1 第三方依赖安装一个都不能少Colmap 的依赖列表是你编译过程中第一个可能劝退你的地方但说白了就是一次性把包装全。我在 Ubuntu 22.04 上实测有效的依赖安装命令如下sudo apt install -y \ libboost-all-dev \ libeigen3-dev \ libfreeimage-dev \ libgflags-dev \ libglew-dev \ libgoogle-glog-dev \ libgtk2.0-dev \ libjpeg-dev \ liblz4-dev \ liblzma-dev \ libpng-dev \ libqt5opengl5-dev \ libsqlite3-dev \ libtiff-dev \ libzstd-dev \ qtbase5-dev这些依赖里面有几个容易踩坑的点值得单独说第一libboost-all-dev装的是 Boost 全量库Colmap 主要用到 Boost 的filesystem、program_options、thread几个模块装全量包虽然有点浪费磁盘但能避免后续“找不到某个 Boost 组件”的诡异报错。第二libfreeimage-dev很关键。FreeImage 是 Colmap 图像读写的基础库某些用 APT 方式装 Colmap 的发行版会漏掉这个依赖导致编译出来的程序无法读取常见图片格式。如果 FreeImage 没装好Colmap 运行时会出现Cannot read image的诡异问题。第三OpenCV 是另一个核心依赖。Ubuntu 22.04 的仓库里有 OpenCV 4.5.4版本完全兼容 Colmap。如果你系统里已经通过源码方式装过 OpenCV可能会遇到版本冲突建议先卸载掉再看看 Colmap 能不能直接通过系统库编过去。如果你需要用到 Ceres Solver做 bundle adjustment 优化的核心库可以额外安装sudo apt install -y libceres-dev装 Ceres 的好处是让 Colmap 的输出 BA 结果更准确。如果你的数据集质量一般、或者图像匹配成功率不稳定建议装上。4.2 源码克隆与版本选择策略依赖齐了之后就可以拉源码了。Colmap 的 GitHub 仓库在https://github.com/colmap/colmap直接克隆主干仓库git clone https://github.com/colmap/colmap.git cd colmap这里有个版本选择的问题。Colmap 的开发节奏比较快主干分支main随时可能引入新特性或者破坏性变更。如果你需要一个稳定的编译环境建议切换到最新的 Release tag 而不是直接用 maingit checkout 3.10我在编译时发现3.9 和 3.10 版本对 CUDA 12.x 的兼容性都很好3.8 及以下版本在 CUDA 12 环境下需要额外处理一些头文件兼容问题。如果你用的 CUDA 版本是 12.x强烈建议直接用 3.9 以上的版本。如果你的网络环境访问 GitHub 不稳定可以先用 git 把仓库下载下来或者找一台网络状况好的机器打包传输。不要在这个过程中频繁切换源容易造成仓库状态混乱。4.3 CMake 配置阶段参数详解与验证编译配置是全文最重要的环节这里我把每一步拆开讲清楚。首先在 Colmap 源码根目录创建 build 目录mkdir build cd build然后执行 CMake 配置命令cmake .. -GNinja \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_CUDA_ARCHITECTURESnative \ -DCMAKE_CUDA_COMPILER/usr/local/cuda/bin/nvcc解析一下这几个参数-GNinja指定用 Ninja 构建系统好处是并行编译效率高报错信息比 Make 更友好-DCMAKE_BUILD_TYPERelease编译优化模式开启 O3 优化。如果是调试 Colmap 源码可以改成 Debug但运行性能会差不少-DCMAKE_CUDA_ARCHITECTURESnative自动检测当前显卡架构让 nvcc 生成适配你显卡的代码-DCMAKE_CUDA_COMPILER/usr/local/cuda/bin/nvcc显式指定 CUDA 编译器。多 CUDA 版本共存时这一步可以避免 CMake 找到错误的 nvcc。还有一个参数值得关注-DCMAKE_CUDA_FLAGS-O3 --use_fast_math--use_fast_math可以让部分数学函数用近似算法代替精确算法换来性能提升。默认情况下不推荐开启因为会损失数值精度如果你处理的图像数据量大、对精度要求又不是特别苛刻可以考虑开启。配置完成后检查输出信息里有没有警告。重点关注两行内容一行是Found CUDA说明 CUDA 被成功识别另一行是CUDA_SIFT_GPU_FOUND或者类似的特征提取相关打印如果这里显示 NOT FOUND说明即使编译成功SIFT 特征提取也还是 CPU 版本就失去带 CUDA 编译的意义了。还有一个常见问题如果你只装了 CUDA Toolkit 但没有/usr/local/cuda/bin/nvcc这个路径说明环境变量没生效或者 CUDA 不是通过默认路径安装的。可以先执行which nvcc看看实际路径然后把 CMake 里的参数改成实际路径。4.4 编译、安装与验证CMake 配置顺利完成之后编译阶段相对省心。执行ninja -j$(nproc)-j$(nproc)会让 Ninja 使用所有 CPU 核心进行并行编译。但这里有个经验之谈如果你的内存小于 16GB建议把线程数减半否则编译过程中多个编译任务同时跑内存会爆掉。编译完成后安装到系统环境sudo ninja install安装完毕后先在终端里验证一下colmap -h如果输出正常的帮助信息说明安装成功。但“安装成功”不等于“CUDA 版本工作正常”我还建议跑一次真实的特征提取验证 GPU 是否被真正调用colmap feature_extractor --database_path test.db --image_path /path/to/your/images --SiftExtraction.use_gpu 1注意观察日志输出如果 CUDA 正常日志里会显示 GPU 设备信息和 SIFT GPU 相关的字样。如果日志里出现 CPU 的提示说明编译时 CUDA 相关模块没有被正确启用。5. 高频报错与排查思路5.1 CUDA 安装环节的报错记录报错一gzip: stdin: invalid compressed>export CC/usr/bin/gcc-11 export CXX/usr/bin/g-115.2 Colmap 编译阶段的报错记录报错一CMake 找不到 CUDA如果 CMake 配置时输出Could NOT find CUDA先确认nvcc --version能否正常执行。能正常执行但 CMake 找不到大概率是你 CMake 版本太旧不认/usr/local/cuda这个软链接。升级 CMake 到 3.22 以上基本能解决。报错二CMAKE_CUDA_ARCHITECTURES相关的 warning配置时会看到类似Manually-specified variables were not used by the project的警告这通常是 CMake 变量名拼写错误或者该项目不识别该变量。Colmap 3.10 对CMAKE_CUDA_ARCHITECTURES的支持已经完善如果你仍然看到相关变量被忽略的提示检查版本是不是太旧。报错三编译过程中内存不足KilledNinja 并行编译时内存打满导致进程被系统杀掉这在 8GB 内存的机器上非常常见。解决方法是限制编译并行度ninja -j4或者更极端一点用-j2。另外一个思路是增加 swap 空间虽然编译速度会打折扣但至少不会中途失败sudo fallocate -l 8G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile报错四libGL.so.1: cannot open shared object file运行 colmap 或者 GUI 界面时偶尔会遇到这个报错常见于 headless 服务器环境。解决方法是安装 OpenGL 库的 32/64 位版本sudo apt install -y libgl1-mesa-dev libgl1-mesa-glx5.3 运行阶段如何确认 CUDA 真在干活很多人编译完就默认 CUDA 生效了其实不一定。除了上面提过的feature_extractor日志验证法还有一个更直接的检查方式在运行 Colmap 的任务时另开一个终端执行nvidia-smi如果看到colmap进程占用了 GPU 显存而且 GPU-Util 有百分比波动说明 CUDA 确实在起作用。如果 GPU-Util 一直是 0%哪怕程序能跑也说明你的编译配置有问题回到 CMake 配置环节检查 CUDA 相关的选项。我个人还有个习惯编译完会跑一个小的 benchmark用同样的数据集对比 CPU 版和 GPU 版的运行时间。差距如果只有 10%~20%那大概率某个环节没生效正常情况应该有数倍乃至一个数量级的差距。另外还有一个细节Colmap 运行时的 SIFT 特征提取 GPU 开关是--SiftExtraction.use_gpu 1匹配阶段的开关是--SiftMatching.use_gpu 1。如果你使用的 Colmap 前端工具比如某些基于 Python 封装的库默认没开这两个选项那即使编译了 CUDA 版实际跑的还是 CPU。这也是我见过不少人“编译时带 CUDA 了但还是很慢”的根本原因。
返回列表