Hierarchical-Localization(下面我都简称 hloc)这名字听起来挺唬人,其实就是视觉定位领域一个非常出名的开源工具箱,把"图像检索 + 特征匹配 + 位姿求解"这一整套流程打包好了。但正因为它是深度学习时代的东西,涉及一堆 Python 依赖、预训练模型、还可能踩上 CUDA 和编译的坑,很多人下完代码卡在第一步就放弃了。这篇攻略就是记录我几次配置和重装 hloc 环境的完整经验,从 conda 隔离到 CUDA 版本选择,再到那些文档里没写清楚的坑,尽量一次说透。
先交代一下这篇攻略适合谁:刚拿到 hloc 源码不知道怎么把环境跑起来的新手,以及之前装过但被各种依赖冲突折磨过、想换个干净姿势重装的旧人。我在实际配置中用的是 Ubuntu 20.04 + conda + CUDA 11.3 这套组合,PyTorch 用的是 1.10 左右的老版本组合。我会在下面的步骤里把为什么这么选讲清楚,而不是只丢给你一堆 pip install 命令。
1. 认识 Hierarchical-Localization 与它的"环境魔咒"
1.1 这个工具箱是干什么的
很多人在 GitHub 上搜到 hloc,第一反应是"哦,一个神经网络库",然后想用自己的图片跑一下位姿估计,结果发现事情没那么简单。hloc 其实是一套视觉定位的完整解决方案,核心思想是"从粗到细":先用全局描述子检索出和查询图最相似的数据库图像,缩小匹配范围;再用局部特征(比如 SuperPoint、SuperGlue)在候选图像上做精细的像素级匹配;最后用这些 2D-3D 对应点通过 PnP / RANSAC 解出相机位姿。
这套流程在 Aachen、RobotCar 这些经典定位数据集上表现不错,也是很多 SLAM 和 3D 重建项目的预处理工具。它的模块化程度很高,特征提取器、匹配器、检索后端都可以替换,所以环境配置也天然复杂——不是装一个包就能跑的。
如果你只是想在自己的数据上快速验证定位效果,那你需要准备的东西包括:一组带位姿的参考图像(或者一个重建模型)、查询图像、以及一整套能运行 Python + PyTorch + COLMAP 的环境。环境问题往往比算法问题更早出现,也是劝退率最高的环节。
1.2 为什么它的环境配置比普通项目更折腾
我认真想过这个问题。hloc 的环境难配,不是因为代码写得多复杂,而是它的依赖链太长且各自独立演进。
第一,它要调用外部工具。COLMAP 负责做三维重建和模型转换;pycolmap 是它的 Python 绑定,版本对不上就会有 API 缺失或者链接错误。
第二,它挂靠深度学习框架。PyTorch 版本和 CUDA 版本必须匹配,而 CUDA 又要和显卡驱动匹配,这中间任何一环不对,你本地可能只能"能导入 torch"但跑不了 GPU,甚至编译模型时直接报错。
第三,它依赖文件需要另外下载。SuperPoint 和 SuperGlue 的预训练权重不是跟着 GitHub 仓库走的,要自己从 Release 页面或者原作者网站下载,一旦忘记,代码运行时才发现,报错信息又不够直接,排查就得花不少时间。
所以我把这篇攻略的重点放在"依赖管理"上——不是让你背熟包名,而是让你理解这条链路里哪些版本容易冲突、哪些选择能省事,这样不管以后装什么项目都能举一反三。
2. 动手前的准备:隔离环境与基础依赖搭建
2.1 用 conda 给 hloc 造一个"专属房间"
我的第一个建议永远是:不要把它装进系统 Python,也不要和你的深度学习主环境混在一起。原因很简单——hloc 依赖的 pycolmap、faiss、kapture 这些包版本约束比较强,不同项目很可能需要不同版本。用 conda 创建一个隔离环境,能在 5 分钟内整个删掉重来,不用清理系统全局的包。
我自己习惯用 Python 3.8 或 3.9 来跑 hloc,因为 PyTorch 的官方预编译包对这两个版本支持最全,Python 3.10 以上虽然也可以装新版 PyTorch,但是某些依赖包(比如老版本 pycolmap)不一定有对应 wheel。创建命令很简单:
conda create -n hloc python=3.8 -y conda activate hloc这里有一个小细节:激活环境后,建议先看一眼默认的 pip 和 python 路径,确认没跑到 base 环境里去。我踩过这种坑,明明 activate 了,但终端 PATH 优先级问题导致 pip 还是装到了别的环境,最后折腾半天才发现是 shell 缓存的问题。
2.2 PyTorch 与 CUDA 版本怎么选
PyTorch 是 hloc 最重要的深度学习依赖,但也最容易出错。我的选择逻辑其实很简单:
先看你机器的显卡驱动支持哪个 CUDA 版本,再决定 torch 版本。运行nvidia-smi,右上角的 CUDA Version 就是驱动支持的最高版本,不代表你电脑里装了对应 CUDA toolkit。PyTorch 的安装包里通常会自带一部分 CUDA runtime,所以实际上你只需要确认驱动版本够新就行。
以我自己常用的组合为例:驱动支持 CUDA 11.4,那么我装 CUDA 11.3 版本的 PyTorch 是最稳妥的:
pip install torch==1.10.0+cu113 torchvision==0.11.0+cu113 -f https://download.pytorch.org/whl/torch_stable.html如果你用的是更新的驱动,比如支持 CUDA 12.x,那直接装 PyTorch 2.x 系列也没问题。这里的关键是:不要在驱动较老的情况下强行装新版 PyTorch,那样 torch 会直接报"CUDA driver version is insufficient"。
如果只是跑 hloc 的 demo,其实 CPU 版本也能跑,只是慢很多。你可以先用 CPU 版把流程跑通,再回来换 GPU 版,这样调试环境时反馈更直观,不会一上来就被显存或驱动问题纠缠。
2.3 COLMAP 的编译选择和安装
COLMAP 是 hloc 做三维重建和位姿估计的关键外部工具。它的安装方式有两种,我按推荐程度排个序:
第一种是用 conda-forge 直接装,省事,版本也比较新:
conda install -c conda-forge colmap -y这个方式在 Linux 下很可靠,它会自动把 COLMAP 依赖的 boost、ceres、cgal 等库一并装好。需要注意的是,如果你之前代码里已经有 COLMAP 的头文件或动态库,可能会冲突,建议在 hloc 环境里只保留 conda 版本,别混着系统版本用。
第二种是源码编译。如果你的场景需要某些自定义功能,或者 conda 装不上,那就得自己编译。编译 COLMAP 整个过程比较漫长,需要预先安装一堆依赖库,我建议非必要不折腾。
装完以后一定要验证一下:
colmap -h如果命令能正常输出帮助信息,说明安装成功。COLMAP 这个环节最容易出现的问题是"命令能找得到,但 hloc 调用时却找不到库",这通常意味着 pycolmap 和 colmap 的版本不匹配,我会在第 3 节详细讲。
3. 核心依赖逐一拆解:不只是装包那么简单
3.1 检索后端 faiss 与 kapture
hloc 在图像检索阶段需要建一个特征索引。它底层用的是 faiss,这是 Meta 开源的相似度检索库,负责在大规模向量集合里快速找最近邻。你在 pip 里直接装 faiss-cpu 其实是最保险的选择,因为 faiss-gpu 在编译安装时对 CUDA 版本敏感,很容易报一些奇奇怪怪的链接错误。
pip install faiss-cpu万一你确实需要 GPU 版,我建议用 conda 装,因为 conda 会处理 CUDA toolkit 的依赖关系:conda install -c pytorch faiss-gpu。但我得说,hloc 的检索阶段对性能要求没那么极限,小场景下 CPU 版完全够用,没必要在这个环节给自己添麻烦。
kapture 是另外一个容易被忽略的重型依赖,它是 hloc 使用的数据格式库,负责把不同数据集统一成一套可扩展的格式。装它之前你需要确认其版本和 hloc 的兼容性,新版本 kapture 可能引入了一些不兼容的改动。最稳妥的方法是直接克隆 hloc 仓库后,按照它的requirements.txt安装,里面的版本号都是维护者测过的。
3.2 特征提取与匹配依赖:SuperPoint/SuperGlue 的资源文件
这部分不算 Python 包,但却是环境配置里最容易卡住的一环。hloc 的默认配置会调用 SuperPoint 和 SuperGlue,这两个模型的权重文件需要你手动下载。
具体来说,SuperPoint 的权重叫superpoint_v1.pth,SuperGlue 的权重叫superglue_outdoor.pth或superglue_indoor.pth(取决于你用在室外还是室内场景)。hloc 的仓库里会有 weights 目录,你需要把下载好的权重文件放进去,而且要保证路径和配置文件里的weights字段一致。
我见过有朋友把权重文件放对了目录,但因为 hloc 是从别的目录启动的,导致相对路径找不到,报错内容只有一行"No such file or directory"。这里我有一个比较稳的做法:下载权重后,在 hloc 项目根目录下建立一个weights/文件夹,然后把权重文件统一放进去,并且之后所有的启动命令都在根目录下执行。
另外,新版的 hloc 还有可能依赖 kornia、einops 这类库做张量变换,比如用 DISK 特征时。如果配置里用到了这些,requirements.txt没列全,你可能会在运行某个 extract 脚本时才发现缺包。建议先装上 kornia 和 einops,避免临时抓瞎。
3.3 位姿解算 pycolmap 与其它小工具
pycolmap 是 hloc 和 COLMAP 之间的桥梁,它负责在 Python 里直接调用 COLMAP 的重建和特征匹配功能,避免频繁通过命令行传文件。这个包版本敏感度极高,我甚至可以说,80% 的环境问题都出在它身上。
pycolmap 的版本需要和你的 COLMAP 主版本匹配。如果你 conda 装的是 COLMAP 3.8,那 pycolmap 也要装对应的 3.8 版本:
pip install pycolmap==0.3.0但有些时候 conda-forge 上的 COLMAP 版本很新,而 pycolmap 的 pip 版本还没跟上,这时候就只能放弃 conda 的 COLMAP,改用源码编译一个指定版本,再在 hloc 代码里指定 bin 路径。这个坑很常见,我会在第 5 节展开。
除了 pycolmap,hloc 还会用到 h5py 读写特征文件,opencv-python 做图像读取和基本几何变换,tqdm 显示进度。这些常规依赖没什么难度,但要注意别把 opencv 装成 headless 版本,不然运行时会突然报 GUI 相关的导入错误(尽管 hloc 不弹窗,但依赖链可能有别的库需要)。
4. 实操记录:从零把环境跑通的完整流程
4.1 安装全过程逐步演示
这里我按自己完整跑通过一次的步骤,把命令串起来给你看。假设你已经在 slam 项目 页面把代码克隆到了本地,那么在终端里依次执行:
cd Hierarchical-Localization conda create -n hloc python=3.8 -y conda activate hloc pip install torch==1.10.0+cu113 torchvision==0.11.0+cu113 -f https://download.pytorch.org/whl/torch_stable.html pip install opencv-python h5py tqdm einops kornia conda install -c conda-forge colmap -y pip install pycolmap==0.3.0 pip install faiss-cpu pip install kapture pip install -e .注意最后一步pip install -e .,这是以开发模式安装 hloc 本身,这样你在本地改动代码后不需要重新安装就能生效。很多人直接把项目文件夹留在那里,用脚本时把路径加进 sys.path 也行,但开发模式更干净。
装完之后,运行一个快速验证:
python -c "import hloc; print(hloc.__file__)"如果能正常打印出路径,说明基本环境已经就绪。接下来就是权重文件的放置:去 SuperGlue 官方仓库 或者 hloc 仓库的 README 里找权重链接,下载后放到weights/目录。hloc 的默认配置会读取这个相对路径。
4.2 验证运行:用一个最小场景确认环境可用
环境配好不等于万事大吉,我习惯用一个最小数据集跑通整个流程,验证 COLMAP 调用、pycolmap 桥接、特征提取这几个环节都没问题。
第一个小测试是 COLMAP 命令测试:
python -c "import pycolmap; print(pycolmap.__version__)"如果这个能输出版本号,说明 pycolmap 导入没问题。这里有个陷阱:即使导入成功,也不代表 pycolmap 能真正调用 COLMAP 的库,真正的考验在运行重建时。
第二个测试是用 hloc 自带的一个小样例(比如 sacle 论文里提供的 demo),跑一遍:
python -m hloc.pipelines.Aachen.extract_features --conf/superpoint_max这个命令会经历特征提取、匹配、重建等多个阶段。如果中途没有崩溃,最后能看到保存下来的特征文件和模型结果,说明整条链路已经通了。
如果这个最小样例跑不过,先不要急着怀疑环境,多半就出在 pycolmap 版本不匹配或权重路径问题上,下一个章节我会把这些高频问题整理成速查表。
5. 常见问题与排查技巧实录
5.1 高频报错速查表
以下是我自己在配置和重装过程中遇到过的最高频问题,整理成表格方便你对照排查:
| 报错现象 | 常见原因 | 解决方法 |
|---|---|---|
No module named 'pycolmap' | 没有安装 pycolmap 或者装到了别的环境 | 激活 hloc 环境后重新pip install pycolmap==0.3.0 |
RuntimeError: Cuda error: no kernel image is available | PyTorch 版本与显卡驱动不匹配 | 换用与驱动对应的 CUDA 版本 torch,或改用 CPU 版本调试 |
COLMAP not foundorcommand not found: colmap | conda-forge 的 COLMAP 没装好或者 PATH 不对 | conda install -c conda-forge colmap -y,再colmap -h验证 |
Could not load dynamic library 'libcudart.so.11.0' | 系统 CUDA 版本与 torch 自带 runtime 不一致 | 使用 torch 自带的 CUDA 版本,安装完整 CUDA toolkit 或在环境中补充 LD_LIBRARY_PATH |
No such file or directory: weights/superpoint_v1.pth | 权重文件缺失或路径错误 | 下载权重放到项目根目录的weights/下,确保启动目录正确 |
AttributeError: module 'pycolmap' has no attribute 'Sift' | pycolmap 版本太旧或太新,API 不兼容 | 换一个与 COLMAP 主版本匹配的 pycolmap 版本 |
kapture: No module named ... | kapture 或相关子模块没有安装完整 | pip install kapture或从源码安装到当前环境 |
| 运行中途内存溢出 OOM | 特征提取器对大图占用显存过多 | 调低 resize 参数,或改用 CPU 模式运行部分环节 |
这些报错里,最让我头疼的是 pycolmap 的版本问题,因为报错信息往往滞后,有时候 API 不存在只在链路深处才暴露。我的经验是:不要一味追求最新版本,hloc 仓库的 README 或 setup.py 里锁定的版本号,往往就是最稳的。
5.2 几个值得分享的排错思路
在配置 hloc 上我踩过不少坑,分享几条通用的排查思路,以后你配任何"依赖多、版本敏感"的项目都能用。
第一,建立"最小链路"思维。不要一上来就跑完整 pipeline,而是拆开验证:先确认 PyTorch 能调用 GPU,再确认 pycolmap 能加载 COLMAP 库,最后才跑完整的特征提取和匹配。这种方式可以快速定位问题出在哪一层,不用在层层报错里猜。
第二,留意 conda 和 pip 混装带来的隐患。conda 安装的 COLMAP 自带依赖库,而 pip 安装的 pycolmap 可能链接到系统里的另一个 COLMAP 版本,两边库版本不一致就会在运行时闪崩。遇到这种情况,我建议把 conda 的 COLMAP 卸载,改为源码方式安装一个明确版本,并在运行前通过python -c "import pycolmap; print(pycolmap.__file__)"检查它加载的路径。
第三,权重下载经常超时。SuperPoint 和 SuperGlue 的权重托管在一些下载服务上,如果用默认方式下载不了,可以考虑让浏览器手动下载后上传到服务器,或者用代理镜像下载。文件本身不大,几十 MB 到几百 MB 不等,但网络原因容易失败,多试几次就好。
第四,运行脚本时尽量保持工作目录一致。hloc 的很多路径是相对路径,比如weights/、outputs/,如果你在别的目录下执行python -m hloc.demo,很容易因为找不到相对路径而报错。稳妥做法是写一个小的 shell 脚本,先 cd 到项目根目录,再执行后续命令。
6. 一些后续可扩展的方向
环境配置好后,很多人会问下一步能做什么。我自己的体会是,hloc 的配置过程虽然繁琐,但一旦跑通,后续的扩展性非常强。
你可以把默认的 SuperPoint + SuperGlue 换成其他特征提取器,比如 DISK、LoFTR、ALIKED,只要在配置里把提取器和匹配器的类名改掉,权重的加载逻辑会自动匹配。这种"插拔式"设计意味着同一套环境可以支撑很多定位评测实验,训练新特征点的验证工作也可以直接复用这套 pipeline。
如果你做的不是视觉定位,而是 3D 重建或 SLAM 地图复用,hloc 输出的特征文件和位姿估计结果也能当做一个较好的预处理工具。比如先借助 hloc 给出初始位姿,再用自己的优化算法做精修,这在很多工程落地场景里是一套高效的工作流。
最后再分享一个小技巧:如果你经常重装环境,一定要把成功跑通时的依赖版本号记录下来,可以用pip freeze > requirements_lock.txt留个底。这样即使半年后环境崩了、代码更新了,你也能照着这份锁文件把旧环境完整复现出来。依赖管理这件事,说白了就是"可复现"三个字,hloc 的配置只是其中的一个典型案例。