引言
本博文对RSS2025的VLN工作进行复现
- 本博文复现过程采用的代码及代码注释(如有):My github repository
- website
- github
- Paper List for VLN: Link
理论解读
现有的视觉语言导航(Vision-and-Language Navigation, VLN)系统通常依赖于预计算地图或使用深度传感器和单目RGB相机构建几何地图,但这些方法在复杂和杂乱的环境中表现有限。 本文主要解决腿式机器人(如四足机器狗或类人机器人)的视觉语言导航问题。
With VLN, a robot is expected to navigate around unseen environments without a provided map following a language instruction直观而言,VLN有点类似于自动驾驶中无图的概念,并且额外加上了语言指令实现人机交互。
而在VLA领域,更是将语言指令转换为action,机器人需要理解输入语言,进行闭环规划以及low-level control。而目前大部分的工作都是依赖于Large Language Models (LLMs)或者Vision-Language Models (VLMs)
研究难点:
- 如何将人类语言指令转换为低级别的腿部关节动作;
- 在不同机器人之间迁移VLN模型;
- 现有的VLN系统在处理连续环境和低级运动控制方面也存在挑战
NaVILA结合了视觉-语言-动作模型(VLA)与运动控制(locomotion)的两级系统来实现VLN,以提高腿式机器人的导航能力。使用视觉语言模型(VILA)处理单视图图像,生成自然语言形式的中间动作指令(mid-level action)。 本质上应该算是VLA,只不过进一步到导航层面,故此为VLN。
如上图所示,NaVILA采用一个VLM来处理单视角图像,同时生成自然语言航路点指令。再由 locomotion policy翻译为真实机器人运动的精确关节运动。
Taming VLMs for Vision Language Navigation
作者采用image-based vision-language models(VILA),而VILA的预训练已被证明对多图像推理特别有效,使其特别适用于理解顺序图像关系至关重要的VLN任务。
VILA由三个主要组件组成:视觉编码器(vision encoder)、投影器(projector)和大型语言模型(LLM)。
- 视觉编码器将输入图像转换为视觉标记序列(visual tokens)
- 这些标记(tokens)通过多层感知机(MLP)投影器映射到language domain。
- 这些投影后的tokens与text tokens一起被发送到LLM进行自回归生成(auto-regressive generation)。
VILA采用三阶段训练过程,包括连接器(connector)的预训练、连接器和LLM的联合预训练以及使用指令调整数据的微调。
- frozen LLM 以及 vision backbones的connector
- 通过text-image交织语料库来训练connector和LLM
- 最后fine-tune全部模块s (vision encoder, connector,LLM)
对于VLN任务中,不同时间的图像具有不同的作用。当前时间的图像用于立即决策,而之前的帧作为记忆库帮助智能体追踪整体进度。 为了更好地处理这两种表示,论文使用导航任务提示(Navigation Prompts)方法,通过区分当前观察和历史帧,并使用文本线索(textual cues)来构建导航任务提示。
这里的 textual cues 可以理解为给不同的观测加不同的token(如上面图2所示)
“a video of historical observations”: for memory frames
“current observation”: for the latest frame
对于VLA的训练:
- 整合VLN中历史的内容与当前的观测到VLM框架中
- 为VLN任务量身定制的专用导航提示
- 利用来自YouTube中人类 touring(巡演)的真实环境视频来提高agent在连续空间的导航能力
- 引入了一个数据集来提升VLN的泛化能力
这些策略将通用的基于image的VLM fine-tune为以导航为目标的agent,同时通过在通用的视觉-语言数据集的训练来保证其强大的泛化能力。the first work to show that direct training on human videos improves navigation in continuous environments
对于来自YouTebe的真实数据,首先基于熵的采样来分为20K个代表性的轨迹。通过MASt3R来从视频中估算粗话camera pose,然后提出step-by-step action,并且采用LLM 重新表述与基于VLM的字幕生成来生成自然语言指令。这样就可以实现利用人类的视频来作为连续导航的数据。
对于locomotion的训练,采用single-stage approach来学习基于视觉的运动控制策略。通过原始的LiDAR点云来构建高度图(height map),同时通过引入一些随机性来减少sim-to-real的gap。 控制器通过VLA模型的输出作为输入,将其转换为速度等控制指令,进而控制关节。
采用VLN-CE-Isaac来端到端训练基于视觉的control policy
而作者更是通过实验发现,所采用的VLA与运动控制(locomotion)的两级系统来实现VLN比起经典的VLN框架要提升17%的成功率。但从结果来看SR也就是50%左右的级别
实验配置
安装配置
PS: H200没有图形,因此换为4090再次配置
- 创建conda环境
conda create -n navila-eval python=3.10
conda activate navila-eval
- 构建Habitat-Sim & Lab (v0.1.7)
# 安装Habitat-Sim 0.1.7,但下面只支持python3.6~3.9,用的3.10需要源码安装
# conda install -c aihabitat -c conda-forge habitat-sim=0.1.7 headless
# 安装Habitat-Lab
git clone --branch v0.1.7 git@github.com:facebookresearch/habitat-lab.git
cd habitat-lab
# installs both habitat and habitat_baselines
python -m pip install -r requirements.txt
python -m pip install -r habitat_baselines/rl/requirements.txt
# 注意,其中的tensorflow==1.13.1似乎已经不支持安装了,改为tensorflow>=2.8.0
python -m pip install -r habitat_baselines/rl/ddppo/requirements.txt
python setup.py develop --all
# #验证
# conda activate navila-eval
# CUDA_VISIBLE_DEVICES=1 python examples/example.py --scene /data/scene_datasets/habitat-test-scenes/skokloster-castle.glb
- 对于Habitat-sim的源码安装,参考Link
git clone git@github.com:facebookresearch/habitat-sim.git #(默认就是v0.1.7)
cd habitat-sim
# git submodule update --init --recursive
# git checkout v0.1.7
# git submodule update --init --recursive #注意切换分支后可能导致部分submodule无效
conda activate navila-eval
# 为了解决NumPy的问题,运行下面:
python ../evaluation/scripts/habitat_sim_autofix.py # 更改habitat-sim/habitat_sim/utils/common.py (更新的代码已经更改了)
pip install -r requirements.txt
# 如果出现路径问题编译不成功,可能因为之前编译过了,进入到habitat-sim目录删除build(rm -rf build)
# python setup.py install
# python setup.py install --headless # without an attached display
pip install cmake
# sudo apt-get install -y --no-install-recommends \
# libjpeg-dev libglm-dev libgl1-mesa-glx libegl1-mesa-dev mesa-utils xorg-dev freeglut3-dev
sudo apt update
sudo apt-get install libgl1-mesa-dev
sudo apt-get install libegl1-mesa-dev
pip install --upgrade pybind11
# rm -rf build
python setup.py install --headless --cmake-args="-DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_CXX_STANDARD=11"
# python setup.py install --cmake-args="-DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_CXX_STANDARD=11"
# python setup.py install --with-cuda --cmake-args="-DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_CXX_STANDARD=11"
- 更新版本的common.py
- Habitat-Sim的源码编译参考
- 若遇到
error: ‘uint16_t’ in namespace ‘std’ does not name a type; did you mean ‘wint_t’?报错,请在对应的文件添加:
#include <cstdint> // 确保包含uint16_t定义
安装后用命令查看是否都是0.1.7: pip list | grep habitat
- 安装VLN-CE依赖
pip install -r evaluation/requirements.txt
- 安装VILA依赖(注意要回到根目录)
# Install FlashAttention2
pip install https://github.com/Dao-AILab/flash-attention/releases/download/v2.5.8/flash_attn-2.5.8+cu122torch2.3cxx11abiFALSE-cp310-cp310-linux_x86_64.whl
# 如果尝试多次都不行可以试试增加超时时间
# pip --default-timeout=1000 install https://github.com/Dao-AILab/flash-attention/releases/download/v2.5.8/flash_attn-2.5.8+cu122torch2.3cxx11abiFALSE-cp310-cp310-linux_x86_64.whl --retries 10
# Install VILA (assum in root dir)
pip install -e .
pip install -e ".[train]"
pip install -e ".[eval]"
# Install HF's Transformers
pip install git+https://github.com/huggingface/transformers@v4.37.2
site_pkg_path=$(python -c 'import site; print(site.getsitepackages()[0])')
cp -rv ./llava/train/transformers_replace/* $site_pkg_path/transformers/
cp -rv ./llava/train/deepspeed_replace/* $site_pkg_path/deepspeed/
- 修改VLN-CE的WebDataset版本
pip install webdataset==0.1.103
- Hugging Face下载模型
- 模型地址a8cheng/navila-llama3-8b-8f
- 安装库
conda activate navila-eval
pip install huggingface_hub
- 到网站,获取token
- 运行脚本
python download_huggingface.py,创建python脚本如下所示
from huggingface_hub import snapshot_download
local_dir = snapshot_download(
repo_id="a8cheng/navila-llama3-8b-8f",
local_dir="/home/guanweipeng/NaVILA/navila-llama3-8b-8f",
cache_dir="/home/guanweipeng/NaVILA/navila-llama3-8b-8f/cache",
token="hf_******", # ✅ 在这里传 token
endpoint="https://hf-mirror.com" # 如果需要走镜像
)
print("模型下载到本地路径:", local_dir)
- 数据集下载
- 参考VLN-CE将R2R 和 RxR 数据下载到
evaluation/data路径;下载方法请参考:服务器数据下载 - 然后下载Matterport3D (MP3D) ,通过网站获取download_mp.py
# conda create -n mp3d python=2.7
# conda activate mp3d
# python download_mp.py --task_data habitat -o /home/guanweipeng/NaVILA/evaluation/data/scene_datasets/mp3d/ --id 17DRP5sb8fy
python download_mp.py --task habitat -o /home/guanweipeng/NaVILA/evaluation/data/scene_datasets666/mp3d/ --id 17DRP5sb8fy
python download_mp.py -o /home/guanweipeng/NaVILA/evaluation/data/scene_datasets666/mp3d/ --id zsNo4HB9uLZ
# python download_mp.py --task minos -o /home/guanweipeng/NaVILA/evaluation/data/scene_datasets6/mp3d/
# 数据实在太大了,也可以尝试从链接:https://cloud.tsinghua.edu.cn/f/03e0ca1430a344efa72b/?dl=1下载,但似乎是没有用的
# 也尝试了用habitat-sim提供的下载但也不work
# conda activate navila-eval
# cd habitat-sim/
# python -m habitat_sim.utils.datasets_download --uids mp3d_example_scene --data-path /home/guanweipeng/NaVILA/evaluation/data/
debug过程
本节记录的是debug的过程,稍微有点乱,可直接跳过~
验证R2R:
cd evaluation
conda activate navila-eval
# bash scripts/eval/r2r.sh CKPT_PATH NUM_CHUNKS CHUNK_START_IDX "GPU_IDS"
bash scripts/eval/r2r.sh /home/guanweipeng/NaVILA/navila-llama3-8b-8f 1 0 "0"
# bash scripts/eval/r2r.sh /home/guanweipeng/NaVILA/navila-llama3-8b-8f 2 0 "1,2"
若报错ImportError: /home/guanweipeng/anaconda3/envs/navila-eval/bin/../lib/libstdc++.so.6: version GLIBCXX_3.4.32 not found (required by /home/guanweipeng/anaconda3/envs/navila-eval/lib/python3.10/site-packages/_magnum.cpython-310-x86_64-linux-gnu.so),先查看环境中的libstdc++.so.6是否包含GLIBCXX_3.4.32
strings /home/guanweipeng/anaconda3/envs/navila-eval/lib/libstdc++.so.6 | grep GLIBCXX_3.4.
#执行安装
conda install -c conda-forge libstdcxx-ng
- 对于无显示器情况,或者GPU不能跑图形的情况
unable to find EGL device for cuDA device 0:
#安装 OpenGL 开发库
sudo apt install libgl1-mesa-dev
#安装 GLFW 库
sudo apt install libglfw3-dev
# 安装 GLEW 库
sudo apt install libglew-dev
#查看安装的pyopengl版本
pip install --upgrade PyOpenGL PyOpenGL_accelerate
#检查EGL版本
ldconfig -p | grep EGL
ldconfig -N -v | grep libEGL
# 最终通过重新安装habitat-sim不为headlee版本似乎可以解决~
python setup.py install --cmake-args="-DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_CXX_STANDARD=11"
- 对于报错跟数据集相关的,比如找不到mp3d或者Navmesh都需要重新确保mp3d数据的下载
# 注意下载数据的方式需要如下,这样下载的数据会额外包含tasks文件夹
python download_mp.py --task habitat -o DATA_PATCH/mp3d --id ID_NAME
对于下面报错:
Platform::WindowlessEglApplication::tryCreateContext(): unable to find EGL device for CUDA device 0
WindowlessContext: Unable to create windowless context
- 换用4090后,报错
cannot get default EGL display: EGL_BAD_PARAMETER
WindowlessContext: Unable to create windowless context
应该是没有对应驱动的原因,接下来安装驱动:
# 添加NVIDIA官方PPA
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt update
sudo apt install nvidia-driver-550
sudo reboot
- 检查
__GLX_VENDOR_LIBRARY_NAME=nvidia glxinfo | grep -i "opengl"会发现有NVIDIA了:
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: NVIDIA GeForce RTX 4090/PCIe/SSE2
OpenGL core profile version string: 4.6.0 NVIDIA 550.144.03
OpenGL core profile shading language version string: 4.60 NVIDIA
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 4.6.0 NVIDIA 550.144.03
OpenGL shading language version string: 4.60 NVIDIA
OpenGL context flags: (none)
OpenGL profile mask: (none)
OpenGL extensions:
OpenGL ES profile version string: OpenGL ES 3.2 NVIDIA 550.144.03
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20
OpenGL ES profile extensions:
__GLX_VENDOR_LIBRARY_NAME=nvidia glxinfo | grep "OpenGL renderer"测试OPENGL
OpenGL renderer string: NVIDIA GeForce RTX 4090/PCIe/SSE2
可视化的视频存放在:./eval_out/CKPT_NAME/VLN-CE-v1/val_unseen/videos
而在终端会实时可视化action指令:
实验效果
- 运行下面代码,对应的在
eval_out文件下会生成大量的视频
cd evaluation
conda activate navila-eval
# bash scripts/eval/r2r.sh CKPT_PATH NUM_CHUNKS CHUNK_START_IDX "GPU_IDS"
bash scripts/eval/r2r.sh /home/guanweipeng/NaVILA/navila-llama3-8b-8f 1 0 "0"
# bash scripts/eval/r2r.sh /home/guanweipeng/NaVILA/navila-llama3-8b-8f 2 0 "1,2"
# 汇总结果以及查看分数
# python scripts/eval_jsons.py ./eval_out/CKPT_NAME/VLN-CE-v1/val_unseen NUM_CHUNKS
实验结果是通过R2R数据集/MP3D模拟器来验证的,指令信息在视频的左下方。
首先先看下面三组视频对应的SPL分别为0.48,0.91,0.96.可以看到episode=1虽然最终能走到终点,但是一开始走的路径并不对,所以对应SPL值较小。
PS:
基于路径加权的成功率(Success weighted by Path Length,SPL):SPL同时考虑了成功率(SR)和路径长度(PL),并对过长的(即效率低)路径进行惩罚
而下面三个例子则是三次测试都没找到路,因此SPL都为0: