第十讲 · 实验课:NaVILA 复现与 VLA 小车部署
前面的课程已经分别讲过视觉、语言、强化学习和机器人控制。我在这一讲把它们放进真实系统:先复现足式视觉语言导航模型 NaVILA,再讨论如何把类似的 VLA 决策链路部署到一辆算力有限的小车上。
这里需要先划清两部分的事实边界:NaVILA 是我们实际完成的课程复现与对比实验;SimLingo 小车实车部署来自实验课给出的可选方案,不能当作我们已经完成的实验结果。
一、NaVILA 要解决什么问题
传统机器人导航常依赖激光雷达、预建地图和针对特定平台设计的导航模块。这样的系统能工作,但换一个场景、换一种机器人,往往需要重新标定甚至重新训练;更重要的是,它很难直接理解“穿过客厅,在沙发旁右转”这样的自然语言指令。
NaVILA 面向四足或人形等足式机器人,目标是让机器人根据单目视觉和自然语言完成导航。它没有让一个大模型直接输出所有关节力矩,而是把任务拆成两个不同时间尺度的层级:
- 高层负责看懂环境与指令,决定“往哪里走”;
- 底层负责保持平衡、避障和控制关节,解决“具体怎么走”。

二、“大脑”和“小脑”的双层解耦
1. 高层“大脑”:视觉语言动作模型
高层模型以历史图像、当前图像和语言指令为输入,输出可读的中层动作,例如:
move forward 75 cm
turn right 30 degrees
内部数据流可以分成四步:
- 视觉编码器把历史帧和当前帧编码为视觉 token;
- 投影器把视觉 token 映射到语言模型可以处理的表示空间;
- 大语言模型把视觉 token 与文字指令放进同一上下文,自回归生成自然语言动作;
- 规则解析器从生成文本中提取动作类型、距离和角度,交给底层策略。
大模型最擅长的是语义理解、空间关系和高层决策,而不是数百赫兹的关节控制。把输出设计成自然语言中层动作,还带来了一个额外好处:人的确能读懂机器人打算做什么,系统更容易排查。
2. 底层“小脑”:运动控制策略
底层策略接收“前进多少”“向左转多少”这样的中层动作,再输出速度命令和关节动作。它要实时处理平衡、足端接触和障碍物,因此训练在 Isaac Sim 中完成,采用非对称 Actor-Critic 架构和 PPO 算法。
课件给出的底层训练信息包括:
- 约 20 000 条带指令的导航轨迹;
- 机器人平台包括 Unitree Go2 等足式机器人;
- 输入包含由 LiDAR 点云构建的 2.5D 高度图;
- 采用单阶段强化学习,而不是 teacher-student 蒸馏;
- 输出把语言动作转换为速度命令和实时关节控制。
高层模型不参与底层策略训练,所以二者可以独立更新。换一种机器人时,可以保留负责语义导航的“大脑”,重新训练与新机体动力学匹配的“小脑”。这正是 NaVILA 能讨论跨 embodiment 泛化的基础。
三、NaVILA 的训练数据
高层“大脑”的训练数据不是只有机器人演示,而是由多种数据混合而成:
| 数据 | 作用 |
|---|---|
| 约 2 000 条 YouTube 第一人称巡游视频 | 从人类日常移动中学习场景变化和导航动作 |
| R2R-CE、RxR-CE 仿真导航数据 | 学习语言指令与连续环境中的导航轨迹 |
| EnvDrop、ScanQA 等辅助导航数据 | 补充环境理解和导航问答能力 |
| 通用 VQA 数据 | 避免模型只会导航而丢失原有视觉语言泛化能力 |
这些数据在 Llama-3 基础模型上进行微调。NaVILA 的思路不是为每个场景手写导航规则,而是让模型从真实人类视频、仿真轨迹和视觉问答中共同学习“看到什么、听到什么、下一步做什么”。
四、我们实际复现了什么
从零训练 NaVILA 需要大量视频、仿真数据和算力,课程实验没有把目标设成完整重训。我们完成的是官方评估流程复现与参数对比:
- 配置独立的
navila-eval环境; - 安装 PyTorch、Habitat-Sim、Habitat-Lab、VLN-CE、NaVILA 和 Flash-Attention 等依赖;
- 准备 Matterport3D 场景与 R2R-VLNCE 任务配置;
- 下载基于 Llama-3-8B 的 8 帧预训练权重;
- 在 Habitat 中运行 R2R 评估,保存日志和视频;
- 在官方开环基线上,增加闭环控制和 4-bit 量化两组对比。
Habitat-Sim 负责三维场景渲染,Habitat-Lab 提供任务与智能体逻辑;Matterport3D 提供室内三维场景,R2R-VLNCE 则规定语言指令、起终点和评估 episode。它们共同构成了“模型在什么世界里、按照什么任务被测试”的实验环境。
五、依赖与环境对齐
具身智能复现不只是“把模型加载起来”。NaVILA 同时依赖大模型、CUDA 算子、旧版导航框架、三维仿真和数据格式,任意一层版本不匹配都可能导致实验无法启动。
1. Habitat-Sim 与 Habitat-Lab
NaVILA 评估依赖旧版 VLN-CE,而 VLN-CE 又绑定较旧的 Habitat-Sim 与 Habitat-Lab API。直接安装新版本会出现 habitat_sim.robots 或传感器接口缺失。实际处理是把 Habitat-Lab 对齐到 v0.1.7,并安装对应版本的 Habitat-Sim 与 habitat_baselines。
2. Python 依赖
旧代码与新生态之间还有 NumPy、Hugging Face 以及周边包的冲突。复现中把 NumPy 固定为 1.26.4、把 huggingface_hub 限制在 1.0 以下,并根据运行报错补齐 lmdb、msgpack_numpy、dtw、fastdtw 等依赖。
3. 权重与显存加载
损坏的 safetensors 文件会报头部 JSON 不完整,只能删除后重新下载。大模型加载还遇到了 meta tensor 问题:low_cpu_mem_usage、device_map 和后续 .cuda() 之间必须保持一致,不能只改其中一个参数。
这些问题说明,具身智能实验的可复现性很大程度上取决于完整记录环境版本和每一次依赖变更,而不只是记录最终模型名称。
六、导航指标应该怎样读
只看“最后到没到”不足以评价导航模型。课程实验采用六个互相补充的指标:
| 指标 | 含义 | 趋势 |
|---|---|---|
| SR | 最终进入目标附近,并主动输出 stop 的比例 | 越高越好 |
| SPL | 用成功率和路径长度共同衡量,绕远路会被惩罚 | 越高越好 |
| OS | 过程中曾经进入目标 3 m 范围即算成功,即使后来又走开 | 越高越好 |
| NE | 最终位置到目标的直线距离 | 越低越好 |
| nDTW | 实际轨迹与人类参考轨迹的相似程度 | 越高越好 |
| 平均步数 | 高层“大脑”下达中层动作的平均次数 | 在效果相当时越少越好 |
SR 回答“最终是否完成”,OS 回答“是否曾经到过”,NE 回答“最后还差多远”,SPL 和 nDTW 则分别检查路径效率与指令遵循。一个模型可以 SR 很高,却因为绕远路而 SPL 很低;也可能最终碰巧到达目标,但没有按照指令要求经过指定区域,导致 nDTW 很低。
七、三组实验结果

| 实验 | 数量 | SR | SPL | NE | OS | nDTW | 平均步数 | 平均路径长 | 耗时 |
|---|---|---|---|---|---|---|---|---|---|
| Exp-1:FP16 开环全量 | 1 839 | 54.21% | 49.55% | 5.22 m | 61.66% | 63.83% | 123.4 | 10.28 m | 约 28.5 h |
| Exp-2:FP16 闭环,shuffle | 300 | 52.67% | 50.85% | 4.28 m | 59.00% | 69.20% | 118.4 | 7.85 m | 约 8.6 h |
| Exp-3:4-bit 开环,shuffle | 300 | 55.33% | 52.01% | 4.08 m | 63.00% | 69.82% | 94.0 | 8.51 m | 约 4.4 h |
| 论文 Table I | 1 839 | 54.0% | 49.0% | 5.22 m | 62.5% | — | — | — | — |
1. Exp-1:复现官方开环基线
开环模式把模型给出的距离或角度拆成一个动作队列。例如模型输出“前进 75 cm”后,智能体连续执行三次 25 cm 的 MOVE_FORWARD,中间不重新观察和推理。
Exp-1 的 SR、SPL、NE、OS 与论文 Table I 接近,说明在当前代码、数据和配置下,评估链路已基本复现,可以作为后续课程实验的基准。指标接近并不能单独证明环境、数据处理和实现细节与论文完全一致。
2. Exp-2:每一步都重新观察的闭环
闭环模式每次只执行一个 Habitat 步:前进约 25 cm 或旋转约 15°。执行后立即获取新画面,再让模型重新决策。
相对全量开环基线,闭环组的 SR 低约 1.6 个百分点,但 SPL 更高、NE 更低、nDTW 更高,平均路径也从 10.28 m 降到 7.85 m。课程案例中还出现了开环在附近兜圈、闭环依靠连续反馈更直接到达目标的情形。
闭环更接近真实机器人“感知—决策—执行—再感知”的运行方式,但代价是模型调用更频繁、推理更慢。还要注意,Exp-2 只评估了 shuffle 后的 300 个 episode,而 Exp-1 是 1 839 个全量 episode;细小差异只能作为课程实验观察,不能直接解释为统计显著的算法提升。
3. Exp-3:4-bit 量化
论文采用 AWQ 把大模型压缩为 W4A16;我们使用的是 bitsandbytes NF4 运行时量化,只量化 LLM,SigLIP 视觉编码器和投影器仍保持 FP16。因此 Exp-3 验证的是 BnB 4-bit 方案,而不是复刻论文的 AWQ 权重。
在 300 个 episode 上,Exp-3 的 SR 为 55.33%、SPL 为 52.01%,与 FP16 结果处于同一量级;约 7 GB 显存即可运行,耗时约 4.4 h。300 个 episode 中有 246 个在 4-bit 与 FP16 下得到相同的成功或失败结果,还有 16 个出现 FP16 失败而 4-bit 成功的情况。
课件提出量化噪声可能偶然帮助模型跳出局部死循环,但这只能算对个别案例的可能解释,不能据此断言 4-bit 比 FP16 更聪明。稳妥结论是:本次子集实验没有观察到明显精度损失,说明低显存部署具有可行性。
八、从仿真走向 VLA 小车
下面是实验课给出的 SimLingo 可选实车部署方案。它展示了如何把“图像 + 语言 → 动作”的 VLA 链路搬到 EasyCar 第二代小车上,但课程材料没有证明我们已经完成这套实车实验。
1. 小车与传感器
小车使用 R300-451W X86 工控机,系统为 Ubuntu 18.04 与 ROS1 Melodic。硬件包括:
- Pixhawk 6C 控制器;
- 移动端 RTK 定位;
- T265 双目摄像头与 D435i 深度摄像头;
- 激光雷达;
- Mini Homer 无线通信链路;
- Scout Mini 底盘。
问题在于:小车算力只适合传感采集和底盘执行,跑不动完整 VLA;有 GPU 的基站电脑运行 Ubuntu 22.04,又没有原生 ROS1 环境。于是系统采用分布式部署。

2. 基站推理,小车执行
| 节点 | 环境 | 职责 |
|---|---|---|
| 基站电脑 | Ubuntu 22.04、GPU、Docker 内 ROS1 Noetic | 接收图像和语言指令,运行 VLA 推理,发布速度命令 |
| 小车 | Ubuntu 18.04、ROS1 Melodic | 运行唯一的 roscore,采集 D435i 图像,执行 /cmd_vel |
Noetic 与 Melodic 都使用 ROS1 通信协议。基站容器使用 host 网络加入与小车相同的局域网,作为普通 ROS 节点连接到小车端的 Master,而不是再启动第二个 roscore。
九、ROS 跨机通信配置
基站端需要设置两个地址:
ROS_MASTER_URI指向小车 IP 的11311端口;ROS_IP填写小车能够访问的基站 IP,不能使用127.0.0.1。
两台机器必须处于同一网段、能互相 ping,防火墙不能阻断 11311,时间还应通过 NTP 或 chrony 同步。
桥接完成后,要分别验证上下行:
- 基站能看到小车发布的话题;
- 基站能持续收到
/camera/color/image_raw; - 基站向
/cmd_vel发布低速测试命令时,小车有正确响应; - 测试结束后能立即发送零速度并停车。
先验证通信,再加载大模型,可以把“网络链路错误”和“模型输出错误”分开排查。
十、为什么 SimLingo 不能直接上车
SimLingo 原本面向城市自动驾驶:画面里有道路、车道线和信号灯,动作空间是方向盘、油门、刹车或未来轨迹。实验小车面对的是室内或场地环境,视角更低、速度更慢,输出则是 ROS 的线速度与角速度。
这就是 Domain Gap:
| 城市驾驶训练域 | 实验小车应用域 |
|---|---|
| 宽阔道路、车道线、信号灯 | 室内或实验场地,通常没有车道线 |
| 汽车视角和高速运动 | 低视角、低速、近距离障碍物 |
| 方向盘、油门、刹车 | linear.x 与 angular.z |
| 交通语义指令 | 前进、后退、转向、停止、跟随等指令 |
直接套用城市域模型会出现动作含义和尺度错配,所以课件给出“采集—微调—验证”三步。
1. 采集
遥控小车完成前进、后退、左转、右转、停止等动作,同步记录 D435i 图像、当时的 /cmd_vel 和对应语言指令。数据要覆盖不同场景与光照,并保持各种指令相对均衡。
2. 微调
把数据整理为“图像、指令、动作 ”三元组。在预训练权重上冻结大部分视觉和语言主干,优先微调动作输出头,使其从汽车动作空间切换到小车的 Twist 空间。
3. 验证
先在验证集检查指令跟随准确率和速度方向,再把小车架空观察轮子转向,最后才在留足空间的地面上低速测试。验证顺序必须是“离线—架空—落地低速—逐步提速”。
十一、在线控制闭环

在线运行的数据流是:
D435i 图像 + 语言指令
↓
基站 VLA 推理
↓
geometry_msgs/Twist
↓
Scout Mini 底盘执行
↓
场景变化后重新采集图像
geometry_msgs/Twist 中:
linear.x控制前进或后退速度;angular.z控制左转或右转角速度。
上层需要以约 20 Hz 持续发布命令。底盘看门狗在约 0.5 s 收不到新指令时会自动停车;即使目标速度不变,也要持续重发同一条命令,既维持运动,又允许下一时刻立刻转向或急停。
十二、安全机制与排障顺序
实车系统必须在模型之外增加确定性的保护:
- 对线速度和角速度限幅;
- 保留底盘看门狗;
- 节点退出或收到“停”时立即发布零速度;
- 首次测试先架空,再落地;
- 留足安全距离,并安排人员随时急停。
出现问题时,按链路从底向上排查:
| 现象 | 优先检查 |
|---|---|
| 看不到对方话题 | 网段、ROS_MASTER_URI、ROS_IP、端口与防火墙 |
| 有图像但小车不动 | /cmd_vel 是否持续发布、底盘是否订阅、看门狗是否超时 |
| 动作方向错误或乱跑 | Domain Gap、动作映射和微调数据是否正确 |
| 容器无法使用 GPU | GPU 透传、驱动与 CUDA 版本 |
| 时间戳或 TF 报警 | 基站与小车是否同步时间 |
十三、从模型到机器人系统
NaVILA 复现展示了一个真实 VLA 系统如何把“大模型擅长的高层理解”和“控制策略擅长的高速执行”分开;SimLingo 小车方案进一步说明,模型之外还需要传感器、网络、ROS、动作空间适配和安全保护。
一个能落地的智能机器人不是单独一张神经网络,而是一条完整闭环:
感知 → 语义理解 → 决策 → 控制 → 物理执行 → 新的感知
这也对应课程开始时的判断:具身智能可以看作复杂不确定环境中的广义控制问题。