先说个真实经历。上个月我在一台跑着 Ubuntu 22.04 的服务器上配 Habitat-baselines v0.1.7,原以为照着 README 半小时搞定,结果从早上十点折腾到下午五点,中途一度怀疑是自己太菜。装完后回头看,问题全集中在版本对应关系、habitat-sim 安装方式、数据路径三块。今天这篇就按我实际踩坑的顺序,把整个流程重新走一遍。
标题里写“全网唯一”确实有点标题党,但这个 v0.1.7 是官方比较早的 tag,网上能搜到的教程要么年代久远、要么只讲主流程不讲坑,如果你也是做具身智能、想在老版本上复现论文基线,或者纯粹想搞清楚 Habitat 三件套怎么协同工作,这篇文章应该能帮你省下我那一整天。
我尽量把每一步的命令、为什么这么做、报错怎么定位都写清楚。下面开始。
1. 跑通之前,先弄清楚 Habitat 三件套的版本血缘关系
很多人装 Habitat-baselines 失败,第一原因不是操作问题,而是根本没搞明白这个仓库和 habitat-lab、habitat-sim 之间的关系。
1.1 谁依赖谁:sim、lab、baselines 的三角关系
这三个项目是分开维护、分开发布的,但它们在实际运行时必须是一套互相匹配的组合。
- habitat-sim:底层仿真器,负责加载 3D 场景、做物理碰撞检测、渲染视觉观测。它是 C++ 写的,Python 层只是封装。
- habitat-lab:中间层 API,定义了环境接口、传感器、任务逻辑(比如 PointNav、ObjectNav 的 reward 计算、碰撞判定、成功指标)。
- habitat-baselines:最上层的算法库,基于 habitat-lab 提供的接口实现 PPO、DQN、DD-PPO 等训练算法。
baselines 并不会自己实现仿真逻辑,它训练智能体时要调用 lab 的HabitatEnv,lab 又调用 sim 去渲染场景、控制智能体位置。所以安装顺序必须是 sim 在最底层、lab 在中间、baselines 在最上面。如果你只装了 baselines,运行时会直接报ModuleNotFoundError: No module named 'habitat',因为habitat这个 Python 包其实是 habitat-lab 提供的。
1.2 v0.1.7 的配套版本和典型运行环境
Habitat-baselines v0.1.7 是 2021 年的版本,当时官方发布时还是以 Ubuntu 18.04/20.04 为主力测试环境,Python 官方推荐 3.8,但我实测 Python 3.9 也可以,3.10 及以上就不要尝试了,habitat-lab 里的很多第三方依赖在 3.10 上会出现兼容性问题,属于给自己找麻烦。
配套版本方面,v0.1.7 对应 habitat-lab 的 v0.2.2 tag。这个对应关系很重要,如果你直接拉 habitat-lab 的 master,接口大概率变了,baselines 跑不起来。
我当时用的是这样一套组合:
| 组件 | 版本 | 备注 |
|---|---|---|
| Ubuntu | 22.04 / 20.04 | 22.04 需要额外装系统依赖 |
| Python | 3.9 | 3.8 也可以 |
| CUDA | 11.3 | 配合 PyTorch 1.10 |
| PyTorch | 1.10.0+cu113 | 官方要求 1.8 以上,1.10 实测最稳 |
| habitat-sim | conda-forge 最新版 | 不需要指定太细的版本号 |
| habitat-lab | v0.2.2 | 必须切 tag |
| habitat-baselines | v0.1.7 | 必须切 tag |
1.3 为什么坚持用 conda:二进制依赖的锅
habitat-sim 是一个大型 C++ 项目,如果你自己从源码编译,需要配 CMake、Bullet、Magnum、OpenGL 头文件等一系列依赖,即使编译成功,后续更新系统库还可能导致动态链接库重新冲突。官方推荐、社区实际使用也最稳的方式是用 conda 安装预编译好的二进制包。
所以我的第一个建议是:不要尝试从源码编译 habitat-sim,除非你实验环境特殊到必须自己改仿真器源码。直接用 conda 从 conda-forge 渠道拉包,省下大量时间。
提示:如果你用无显示器服务器,一定要装 headless 版本,否则运行时初始化渲染上下文会失败。这个我后面会单独讲。
2. 源码获取和环境准备:每条命令背后的实际原因
这个阶段看着简单,但很多人就是在这里开始踩坑。我把关键命令拆开说。
2.1 克隆仓库与切换 tag
先创建并激活 conda 环境:
conda create -n habitat python=3.9 conda activate habitat然后克隆两个仓库:
git clone https://github.com/facebookresearch/habitat-lab.git git clone https://github.com/facebookresearch/habitat-baselines.git克隆完成后不要急着安装,先切到对应 tag:
cd habitat-lab git checkout v0.2.2 cd ../habitat-baselines git checkout v0.1.7这一步特别容易忽略。如果你直接装默认分支,baselines 的run.py调用的接口和最新版 lab 不一定对得上,轻则命令跑不通,重则连导入都报错。
2.2 安装底层的 habitat-sim
我实测下来最稳定的安装方式:
conda install -c conda-forge habitat-sim如果你的服务器没有显示器,安装 headless 版本:
conda install -c conda-forge habitat-sim headless这里有个细节需要注意:headless在这里相当于一个额外的 feature 标签,并不是一个独立的包名。加了它之后,仿真器会忽略本机显卡显示输出,只做离屏渲染,这对 SSH 远程训练非常关键。
如果你在安装时 conda 解析依赖很慢,可以给 conda 配上国内镜像源,把~/.condarc换成清华源或者中科大源都行。这和你网络环境有关,不是必选项,但能节省很多等待时间。
2.3 PyTorch 与 CUDA 版本匹配的实测建议
habitat-baselines v0.1.7 官方要求 PyTorch 1.8 以上,但我实测下来最省心的是 PyTorch 1.10.0 配 CUDA 11.3:
pip install torch==1.10.0+cu113 torchvision==0.11.0+cu113 \ -f https://download.pytorch.org/whl/torch_stable.html安装之后先验证一下:
python -c "import torch; print(torch.__version__, torch.cuda.is_available())"只要输出1.10.0+cu113 True就说明 GPU 环境是通的。
这里必须提醒一句:不要图新装 PyTorch 2.x。我试过一次,虽然import torch没问题,但 habitat-baselines 里的utils模块调用了torch.distributed的一些旧接口,2.x 里已经调整了默认初始化方式,导致多卡训练直接起不来。如果你想省时间,就按老版本环境来。
3. 编译安装阶段最容易翻车的三个环节
PyTorch 装好之后,接下来是让 Python 能识别 habitat-lab 和 habitat-baselines。这个阶段有三个高频坑。
3.1 安装 habitat-lab 时的顺序问题
很多人先装 baselines,再装 lab,结果 pip 会尝试从 PyPI 拉一个老旧的 habitat 包,或者干脆报错。正确顺序是先 lab 后 baselines:
cd habitat-lab pip install -e .-e表示 editable 模式,会创建一个软链接到你的源码目录,后续你改了 lab 的 Python 文件不需要重新安装。而且它会在当前 Python 环境里注册habitat这个包。
注意:安装前确认当前 conda 环境是
habitat,很多人因为忘记激活环境,把包装到了 base 环境里,后面import habitat却永远找不到模块。
如果这里有编译报错,通常和缺少系统依赖有关。Ubuntu 22.04 上我遇到过error: command 'gcc' failed,这时候先安装:
sudo apt update sudo apt install build-essential cmake libgl1 mesa-utils libglu1-mesa-dev装完再重新执行pip install -e .就可以了。
3.2 habitat-baselines 安装时的依赖冲突
cd ../habitat-baselines pip install -e .这个步骤本身没什么复杂操作,真正麻烦的是它会把gym、numpy、scipy、opencv-python等一大堆依赖拉到你的环境里。如果你之前装过其他 RL 库,很容易出现numpy版本回退或者gym版本冲突。
我遇到最典型的问题:安装之后import gym报AttributeError: module 'numpy' has no attribute 'bool'。这是因为 numpy 1.24 移除了np.bool,而老版本 gym 还在用。解决办法是降级 numpy:
pip install "numpy==1.23.5"装完之后先跑一遍自检:
python -c "import habitat_sim; print(habitat_sim.__file__)" python -c "import habitat; print(habitat.__file__)" python -c "import habitat_baselines; print(habitat_baselines.__file__)"这三条命令只要各自输出了路径,说明三件套都已经就位。如果第一条就报错,回头看 habitat-sim 是否装到了这个环境里。
3.3 libGL 相关报错:Ubuntu 22.04 新增的坑
import habitat_sim时如果报错libGL.so.1: cannot open shared object file,说明当前系统缺少 OpenGL 运行库。这是 Ubuntu 22.04 上很常见的问题,因为默认安装的 Python 环境不会自动带上 libGL。
解决方式:
sudo apt install libgl1 libglib2.0-0或者从 conda 侧补:
conda install -c conda-forge libgl这个问题在 20.04 上不太明显,在 22.04 上几乎必踩。
4. 数据集准备:不弄好路径,训练根本起不来
代码环境配好之后,下一步是准备数据。这里的水比想象中深,我见过很多人环境没问题,卡在数据上半天。
4.1 Scene 数据和 Episode 数据,到底有什么区别
一个完整的导航任务数据由两部分组成:
- Scene 数据:3D 场景本身,通常是
.glb格式的文件,比如 Gibson 数据集的各房间模型。仿真器加载这个场景,才能渲染出画面、计算碰撞。 - Episode 数据:一系列任务的描述文件,通常是
.json.gz,里面每条 episode 包含智能体的初始位置、目标位置、场景名称等。
两者是配套关系。你下载了一个 Gibson 场景,对应的 episode 文件里会引用这个场景的名字,如果场景文件不存在,训练启动时就会报错或者直接创建一个空数据集。
4.2 数据下载与目录摆放规范
在 habitat-baselines 项目根目录下,默认约定的数据结构是这样的:
habitat-baselines/ └── data/ ├── datasets/ │ └── pointnav/ │ └── gibson/ │ └── v1/ │ ├── train/ │ │ └── train.json.gz │ └── val/ │ └── val.json.gz └── scene_datasets/ └── gibson/ └── (一堆 .glb 文件)下载数据集时,不要自己手动去网上乱搜。老版本 habitat-sim 提供了一键下载脚本:
python -m habitat_sim.utils.datasets_download --uids gibson_habitat这个命令会自动创建data/scene_datasets和data/datasets目录。如果你需要使用 HM3D 数据集,命令是:
python -m habitat_sim.utils.datasets_download --uids hm3d但要注意,有些数据集需要额外申请权限,尤其 Matterport3D。下载下来之后一定要对着目录结构检查一遍,我见过太多人把.json.gz放错位置,训练时报路径错误,折腾半天才发现是目录层级多了或者少了一层。
4.3 修改配置文件的正确姿势
v0.1.7 的 PointNav PPO 示例配置在configs/ppo/ppo_pointnav.yaml。打开之后,重点检查几项:
TASK_CONFIG: DATASET: TYPE: PointNav-v1 SPLIT: train DATA_PATH: data/datasets/pointnav/gibson/v1/{split}/{split}.json.gz SIMULATOR: SCENE: data/scene_datasets/gibson/Allensville.glb其中{split}是运行时动态替换的占位符,会根据run.py传入的--run-type或者配置里的训练验证 split 换成train或val。很多人不知道这个占位符机制,把路径写死了,结果训练和验证时加载同一批数据。
还有一点,SIMULATOR.SCENE在旧配置里不是必填项,但如果你的 episode 里引用的场景名与实际文件名不一致,仿真器加载会失败。这时候可以临时在配置里指定一个场景文件,但更好的做法是保证数据集目录完整性。
提示:千万不要把数据集放到中文路径或者带空格的路径下,Git 项目和 conda 环境对这类路径处理得很不稳定,我遇到过莫名其妙的报错,最后发现是路径问题。
5. 启动 PPO 单智能体训练:从命令到日志
到这里,前面所有坑都绕过之后,真正的训练才刚开始。这个阶段也有自己的问题。
5.1 训练命令逐参数拆解
在项目根目录执行:
python habitat_baselines/run.py \ --exp-config configs/ppo/ppo_pointnav.yaml \ --run-type train--exp-config指定的是实验配置文件,--run-type有三个选择:train、eval、inference。直接跑训练时用train。
如果你的机器只有一张显卡,可能还需要在配置里检查:
TORCH_GPU_ID: 0或者在命令行指定:
CUDA_VISIBLE_DEVICES=0 python habitat_baselines/run.py ...我遇到过不少新手,明明机器上有多张卡,但 PyTorch 默认只在 0 号卡上占显存,其他卡空着,还以为是程序不支持多卡。v0.1.7 的 PPO 单卡实现本身也没做多卡数据并行,想多卡训练得换 DD-PPO 配置,或者自己改代码。这个版本不是开箱即用的多卡框架,预期要放平。
5.2 启动失败排查清单
训练启动阶段碰到的问题,大多是环境或者配置导致,我整理了一个排查清单:
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
启动后立刻报FileNotFoundError | 数据集路径不对 | 检查data_path和scene_datasets目录 |
报AssertionError: Dataset is empty | episode 文件与场景不匹配,或 json.gz 未正确加载 | 单独写脚本打印数据集长度,确认有内容 |
报CUDA out of memory | batch size 太大 | 调小RL.PPO.batch_size或降低分辨率 |
| 启动后卡住不打印日志 | 数据集加载过程中,没有使用进度条 | 等几分钟,或者先检查数据量大小 |
报NameError: name 'habitat_sim' is not defined | 环境混用,sim 装到别的环境 | 确认conda activate habitat生效 |
有一次我启动后一直停在initializing environment,等了十分钟还没反应,最后发现是网络驱动器上的数据集读取太慢。如果数据放在 NFS 挂载盘上,建议先拷到本地 SSD 再训练,不然每个 episode 加载都要卡顿很久,fps 会低到让人怀疑人生。
5.3 训练日志怎么看:loss、reward、fps
训练启动后,终端会打印类似这样的日志:
[INFO] Training: num_updates=1560 [INFO] update: 1, mean reward: 0.1234, num_episodes: 64, fps: 45 [INFO] update: 2, mean reward: 0.1456, num_episodes: 128, fps: 49这里几个关键指标:
mean reward:最近一批 episode 的平均奖励,PointNav 任务早期分数很低很正常,不代表训练失败。num_episodes:累计完成的 episode 数量,用来判断数据采样是否正常。fps:每秒执行帧数,反映仿真器运行速度。Gibson 场景在单张 3090 上跑到 40-50 fps 是正常的,如果你只有个位数 fps,先检查是不是 CPU 算碰撞、GPU 利用率上不去,再检查数据集是否在慢速存储上。
TensorBoard 日志会输出到tb/目录,如果你想实时看曲线:
tensorboard --logdir tb打开浏览器访问http://服务器IP:6006就能看到 reward、loss 曲线。这里有个老版本的小问题:v0.1.7 默认可能只记录部分 scalar,如果你看不到 policy loss,可能是配置文件里TENSORBOARD这个 feature 没开。检查RL.TENSORBOARD是否为True。
6. 评估与可视化:隐藏的雷区
训练完模型之后,第一件事自然是评估效果,但这里还有几个容易忽略的点。
6.1 评估命令与常见误区
评估时使用:
python habitat_baselines/run.py \ --exp-config configs/ppo/ppo_pointnav.yaml \ --run-type eval但直接跑大概率报错:找不到 checkpoint。因为评估需要你明确指定模型权重路径,在配置文件里有这样一个字段:
EVAL_CKPT_PATH_DIR: data/checkpoints/ppo_pointnav/它要求目录下存在.pth文件。训练默认会把模型保存到data/checkpoints/下,但训练和评估如果在不同时间跑,一定要确认目录名是否一致。
另一个常见误区是直接复制训练配置跑评估,没有修改SPLIT。训练用的是trainsplit,评估应该用valsplit,否则你评估的是智能体在训练集上的表现,指标虚高,没有参考价值。修改配置时把TASK_CONFIG.DATASET.SPLIT改成val。
6.2 渲染视频时容易忽略的条件
v0.1.7 支持评估时输出智能体视角视频。相关配置一般长这样:
VIDEO_OPTION: ["disk", "tensorboard"] TENSORBOARD_DIR: tb VIDEO_DIR: video_dir如果你在 headless 服务器上跑,即使装了 headless 版本,视频渲染也可能出现黑屏。这个问题不是模型问题,而是离屏渲染上下文没有正确初始化。一种解决方式是给运行命令加上虚拟显示:
xvfb-run -a python habitat_baselines/run.py ...在 Ubuntu 上先安装:
sudo apt install xvfb跑完之后到video_dir下看看有没有 mp4。如果没有,检查ffmpeg是否安装。老版本依赖外部ffmpeg命令,很多容器镜像里默认没有:
sudo apt install ffmpeg这个坑我印象非常深,因为当时模型 checkpoint 一切正常,就是视频没生成,查了半天最后发现是 ffmpeg 缺失。
6.3 我踩完坑之后留下的经验清单
最后分享几条实操经验,不是文档里会写的,但能救命:
第一,整个安装过程最好全程记录下来,包括每一个pip install和conda install。因为环境挂掉后重建很痛苦,记录下来了可以直接复制执行。我甚至会把conda env export > environment.txt存一份,虽然这个文件不能完全复现 conda-forge 的源,但至少能看清大版本。
第二,遇到报错不要急着重新安装整个环境,先看报错栈里最后一行是哪个模块抛出的。绝大多数问题都是单个依赖版本问题,升级或降级一个包就能解决,我踩过的坑中,有近一半是 numpy、scipy、gym 之间的兼容性问题。
第三,v0.1.7 是 2021 年的版本,如果你不需要复现特定论文的基线,可以优先考虑直接用新版 habitat-lab 和 habitat-baselines 的 master 分支,新版的 API 更规范、支持的数据集更多。但如果你因为论文代码锁定在这个版本,那本文前面这些坑就是你绕不过去的路。我个人的建议是:在一个独立的 conda 环境里跑这套老版本,别跟其他项目混在一起,这样哪天不想要了直接删环境,不牵连其他工作。
这次复现虽然折腾,但跑通之后我对 Habitat 三件套的边界理解比看文档清楚得多:sim 管渲染和物理,lab 管任务定义,baselines 管算法参数。希望这篇文章能帮你少走点弯路,一次性把环境配好跑起来。