论文阅读及复现笔记之——《NaVILA: Legged Robot Vision-Language-Action Model for Navigation》

2025-11-18

引言

本博文对RSS2025的VLN工作进行复现

理论解读

现有的视觉语言导航(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的联合预训练以及使用指令调整数据的微调。

  1. frozen LLM 以及 vision backbones的connector
  2. 通过text-image交织语料库来训练connector和LLM
  3. 最后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的训练:

  1. 整合VLN中历史的内容与当前的观测到VLM框架中
  2. 为VLN任务量身定制的专用导航提示
  3. 利用来自YouTube中人类 touring(巡演)的真实环境视频来提高agent在连续空间的导航能力
  4. 引入了一个数据集来提升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再次配置
  1. 创建conda环境
conda create -n navila-eval python=3.10
conda activate navila-eval

  1. 构建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

  1. 安装VLN-CE依赖
pip install -r evaluation/requirements.txt
  1. 安装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/
  1. 修改VLN-CE的WebDataset版本
pip install webdataset==0.1.103
  1. Hugging Face下载模型
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)
  1. 数据集下载
  • 参考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值较小。

episode=1
episode=2
episode=3
PS:
基于路径加权的成功率(Success weighted by Path Length,SPL):SPL同时考虑了成功率(SR)和路径长度(PL),并对过长的(即效率低)路径进行惩罚

而下面三个例子则是三次测试都没找到路,因此SPL都为0:

episode=4
episode=5
episode=6

参考资料