logo Mr.Robota 具身智能学习手册
第十五章:Challenge竞赛

VLNVerse 比赛经验:从导航基线到双系统迁移

在家庭仿真场景里,机器人听到一句导航指令后,需要根据相机画面持续判断方向、选择动作,并在目标附近主动停止。一次预测正确只解决了其中一步;整条轨迹能否成功,还取决于场景是否加载、相机是否正确、动作执行是否一致,以及模型能否在陌生房间里恢复偏离。

这篇经验分享整理我们参加 VLNVerse 2026 挑战赛时的基线训练、InternVLA 迁移、协作训练和提交实践。线上回执中,细指令成功率由基线的 32.0% 提高到 InternVLA 零样本的 48.7%;粗指令的相同迁移却由修复后基线的 27.3% 降到 22.7%。两种指令需要分别验证,增加训练也没有自动带来改善。

文中的线上成绩对应具体提交编号,本地成绩对应实际完成的评估条数。2026 年 7 月 17 日留存的合作者榜单成绩为粗指令 46.0%、细指令 59.3%,当时综合排名第 7;这不是比赛结束时的最终名次。我们没有在归档材料中找到最终榜单回执。

配套材料:逐条验证摘要、提交包检查脚本、适配权重使用说明。逐条摘要从原始评估文件提取,保留任务标识和数值指标,未包含私人运行日志。

公开模型与配套材料:Datawhale / VLNVerse 粗指令适配实验归档。这是表 5 中的 6 月 22 日实验权重,包含扩大评估后的退化记录。权重以 41 个分片发布,配套脚本可恢复与原件字节一致的文件;它不对应 48.7% 的零样本线上成绩。

赛后资产处理记录见 归档清单。场景和训练轨迹载荷已经从本次工作副本删除,重新运行闭环仿真前需要按第 10 节来源恢复;失败试训权重已删除,实验元数据保留。

1. 任务、机器人和评估方式

本次参赛路径使用 H1 人形机器人、Isaac Sim 4.5 和 InternUtopia。场景是酷家乐室内住宅资产,包含不同房间、家具、门口和走廊。各住宅的面积、可达区域和路线长度不同,不能用一个固定的“家庭面积”描述全部测试任务。

导航模型主要处理视觉、指令和动作决策。离散动作通常是停止、向前、左转和右转;双系统方法还涉及连续局部轨迹与执行接口。底层运动由既有机器人控制与仿真链路承担,但相机高度、俯仰角、碰撞体和运动步长仍然会影响导航结果,不能当作无关实现细节。

粗指令通常提供较高层的目标或路线信息,细指令提供更详细的导航描述。它们是指令粒度差异,不是“宽松距离阈值”和“严格距离阈值”的区别。每种指令都可以计算多个距离阈值下的成功率。

表 1:本次重点使用的评估指标。

指标 含义 用来判断什么
SR@3[3 米阈值成功率] 结束时满足官方 3 米到达条件的比例 是否最终正确到达并停止
OSR@3[3 米阈值轨迹经过成功率] 整条轨迹是否曾进入目标附近 是否曾经走到,但随后走开或停止错误
SPL@3[3 米阈值路径效率加权成功率] 成功与行走效率的联合指标 成功是否伴随大量绕路
NE[导航误差] 最终位置到目标的距离 停下时距离目标还有多远
TL[轨迹长度] 实际行走路径长度 是否早停、几乎不移动或过度探索
NDTW[归一化动态时间规整相似度] 预测路线与参考路线的相似程度 路线整体是否接近参考

局部日志使用的 OS 字段需要按对应评估器核对,不能仅凭名字断言其阈值与线上一致。路线相似度高也不代表成功率高,最后的停止位置仍可能不正确。

比赛后期改为 Overall[综合任务]:粗指令和细指令各评估 150 条,综合得分为两者 3 米成功率的算术平均。缺失一侧按零计分;旧的独立赛道提交不会自动迁移到新榜单。最终压缩包根目录要求包含:

textsubmission_overall.zip
├── coarse_challenge.json.gz
└── fine_challenge.json.gz

我们实践的是分别生成两侧轨迹、再组合提交。主办方通知规定了结果文件和平均方式,没有在该通知中规定必须共用一套权重;是否允许不同方法及跨队共享,仍应按对应比赛完整规则执行。

2. 先把数据和环境做成可核验的工程

项目最早的难点是大文件下载。官方场景约 312 GB,预构建数据约 179 GB,此外还有机器人资产、预训练编码器和缓存。安装包、原始资产、处理结果和模型同时存在时,实际磁盘占用明显高于下载页面显示的体积。

建议把源码与大文件分开,并让配置引用统一的数据根目录:

textworkspace/
├── source/          # 源码及固定版本
├── configs/         # 训练与评估配置
└── reports/         # 小型结果摘要
data-root/
├── envs/            # 运行环境
├── datasets/        # 场景与轨迹
├── models/          # 原始权重与训练结果
├── cache/           # 可重新生成的缓存
└── evaluations/     # 逐条结果与视频

下载过程中可以比较直连与代理、使用断点续传,并适当增加并发。吞吐量稳定以后,长间隔检查比不断重启下载更有价值。但下载程序退出成功,只能证明它完成了已知任务,不能证明任务清单本身完整。

我们曾用目录存在和部分文件校验判断“资产完成”,随后训练发现单条 rgb.npy 缺失。更深的审计发现,本地训练资产有成片轨迹目录缺失。粗指令和细指令清单分别缺失 932、931 个轨迹目录,原来的检查没有逐条覆盖到这些目录。

后来按官方训练划分重建文件清单,从原始发布源补下载,最终核验到 7,928 条训练轨迹、47,568 个标准文件,缺失轨迹和缺失文件都为零。这个问题的直接原因是本地资产不完整,现有记录不足以把所有缺失都归因于某一次网络断开。

完整性检查应该沿着训练实际读取的路径进行:先枚举划分文件中的轨迹标识,再检查每条轨迹所需文件、图像帧数、动作帧数和解码结果。启动时跳过坏样本能避免训练中途退出,但必须记录跳过数量;它不能替代资产修复。

3. 样本数不一致,先检查资产,再检查采样规则

协作训练时,我们本地文档写粗指令 122,472 个样本、细指令 40,955 个样本,合作者却读出 150,009 和 50,366。表面上看像是加载器版本不一致,实际同时存在数据完整性和采样策略两个因素。

表 2:训练样本数的不同来源。

数据与加载方式 粗指令 细指令
早期本地不完整资产 122,472 40,955
完整资产,每 4 帧采样,不额外追加末帧 150,009 50,366
完整资产,每 4 帧采样,必要时追加末帧 158,871 53,319
另一同步版本,过滤不足 3 个未来帧的样本 141,063 47,368

这几组数字不能混用。固定数据文件还不够,还需要固定加载器版本、末帧策略和未来帧过滤条件。

在当时 format == "vlnverse_action" 的动作标签分支中,样本枚举使用 sample_step=4,不使用 predict_step_num=32 或 num_future_steps=4 来决定数量,也没有停止截断和参考路径、目标过滤。这两个未来窗口参数属于模型其他路径,不能仅凭名字推断它们控制当前数据分支。

协作时应交付完整加载器、数据注册表、环境依赖和启动配置。把配置名写进说明、但把实际加载器放在另一个未跟踪的独立克隆目录里,会让两台机器运行出不同实验。

4. 基线与零样本迁移的实际收益

最初使用 CMA-CLIP[跨模态注意力与图文表征基线],随后接入 InternVLA-N1-DualVLN。后者使用双系统思路,高层根据视觉和语言更新导航决策,局部轨迹模块执行运动。迁移时既要接模型,也要对齐机器人、相机、场景读取和动作接口。

表 3:有编号可追踪的早期线上提交,单位为百分比。

提交编号 方法或修改 指令 3 米成功率 证据
796235 CMA-CLIP[跨模态注意力与图文表征基线] 粗 26.7 线上回执
796239 CMA-CLIP[跨模态注意力与图文表征基线] 细 32.0 线上回执
799486 同一基线,修复一条静止兜底轨迹 粗 27.3 线上回执
800585 InternVLA 零样本,重规划与评估链路修复 粗 22.7 线上回执
800588 InternVLA 零样本,重规划与评估链路修复 细 48.7 线上回执
834183 合作者当时提交,具体权重归属需对应实验材料 粗 / 细 46.0 / 59.3 7 月 17 日留存榜单

细指令从 32.0% 到 48.7% 是增加 16.7 个百分点,粗指令则没有从相同迁移中获益。我们因此保留每侧独立候选,而不是把“模型更大”当作所有任务都更好的依据。

后来准备过“合作者粗指令 46.0% + 本地细指令 48.7%”的组合包,算术平均约 47.35%。这是组合估算,现有记录没有该组合的成功提交回执。合作者同一时期已有细指令 59.3%,说明交换文件时还应交换提交编号和权重版本,否则可能把更好的结果替换成旧版本。

5. 持续左转和图像噪点,要从模型实际输入查起

迁移初期出现了模型持续输出左转的现象。一次探针检查覆盖 10 条任务,发现传给高层模型的 10 张图像全部是黑图。原因是场景读取器只寻找 <scan>.usda,而本地对应资产入口为 start_result_navigation.usd。路径修复后,10 张输入都不再全黑,动作也从重复左转变为多种方向。

这一步应先于微调。训练一个看不到环境的模型,无法修复场景根节点加载错误。排查顺序可以是:核对场景入口文件、截图模型实际接收的相机、检查像素统计与朝向,再对照同一画面下原始权重的输出。

相机还需要对齐官方资产。当 h1_internvla.usd 可用后,我们优先使用 torso_link/h1_1_25_down_30。此前的 torso_link/h1_pano_camera_0 不能视为等价输入。分辨率相同也不意味着视角相同。

噪点与黑图是不同问题。实时渲染、采样光照、降噪、预热和图像捕获时机都可能改变输出。若录像和模型使用同一相机帧,渲染噪点就可能影响推理;只有录像来自独立展示相机或后处理时,才可能主要影响展示质量。

我们曾以高质量路径追踪辅助核验,随后在官方评估链路增加 render_profile='pathtracing_fast',改善持续转圈和步数耗尽问题。因此不能把最早“正式评估一律用快模式”的计划写成最终配置。训练图像、验证图像、展示视频应分别登记来源,模型对比则要保持渲染配置一致。

6. 十条全成功,并不代表比赛能拿满分

一次低成本改动把高层前进重规划间隔从 8 改为 4,保持原始权重和最大步数不变。在 InternNav 的固定 10 条验证中,成功率从 60% 提升到 100%,看起来非常显著。但扩展到 50 条后,只从 48% 提升到 50%,对应多成功一条。

表 4:同一次迁移中,规模和评估链路对结果的影响。

条件 实际完成条数 成功率 路径效率加权成功率
InternNav 原始权重,初始配置 10 60% 49.78%
InternNav 原始权重,重规划间隔 4 10 100% 89.46%
InternNav 原始权重,初始配置 50 48% 40.84%
InternNav 原始权重,重规划间隔 4 50 50% 42.44%
比赛官方链路,重规划间隔 4 与渲染修复 10 70% 57.19%
比赛官方链路,同上 50 46% 40.47%

后两行与前四行并非同一个评估实现,不能混在一起挑最高值。InternNav 的 vln_distributed 和比赛仓库的 vln_multi 在环境与执行链路上存在差异,最终候选应在比赛链路上验证。

建议把评估分成三个目的:3 条检查加载和动作接口;固定、跨场景的小集合筛掉明显退化;完整验证集用于选型。正式比较需要相同任务标识、相同种子、相同评估器和相同停止判据,并保留每条结果。十条测试中的一条成功就占 10 个百分点,很容易产生令人误判的提升。

官方环境也出现过长评估停滞。分块重启可以降低单个进程长时间运行的影响,但恢复时必须按任务标识去重,并确认所有应测任务都完成。我们的一次 50 条评估通过 start_eval_chunked.sh 两次恢复后完成;这和下面主动停止的 12 条实验性质不同。

7. 微调的失败,比损失曲线更有信息

我们试过只训练语言输出头,也试过视觉融合层加语言输出头。两者都降低了训练损失,但没有在固定验证集合上超过原始权重。

表 5:训练分支与局部验证结果。

分支 训练或评估条件 结果与决策
语言输出头短训 500 步,原生导航验证实际完成 17 条 成功率与原始权重同为 58.82%,不能证明与论文全量结果对齐
语言输出头 1,000 步,同一 10 条迁移验证 成功率 50%,原始权重为 60%
视觉融合层加语言输出头 1,000 步,约 1 小时 3 条为 100%,扩大到 10 条为 40%,原始权重为 60%
首次 H100 多卡训练导出 张量审计与首条推理 大量零占位张量,重复无效字符,属于导出问题
6 月 22 日适配权重 粗指令同一 10 条 40%,原始权重为 20%
同一适配权重 细指令同一 10 条 30%,对应官方链路原始权重为 70%
同一适配权重 原计划粗指令 50 条,完成 12 条后停止 1 条成功,即 8.33%;不是完整 50 条指标

最后一项主要表现为短轨迹和早停。已有记录说明当时因质量较差主动停止,不能写成“运行到 50 条导致仿真崩溃”。十条筛选通过后仍然可能大幅下降,原因既可能是覆盖不足,也可能是模型学到了不合适的停止策略。

“官方配置给了很多训练轮数,是否应该跑满”没有固定答案。轮数必须结合完整样本数、采样方式、有效批大小与优化器步数来理解。加载器改变后,同一轮数意味着不同训练量。检查点选择应依据固定验证协议,不能根据损失下降或预设轮数直接宣布收敛。

8. 多卡训练与渲染工作站怎样协作

我们使用支持光线追踪的工作站完成仿真、图像检查和闭环评估;合作者的 8 张 H100 用于已有轨迹上的训练。高训练吞吐不等于适合运行相同渲染后端。把图像和动作数据准备好之后,训练侧不必每一步启动仿真。

多卡协作中有两个具体错误值得保留。

第一个发生在 set_model():启动脚本传了 tune_lm_head=True,但函数把语言输出头是否训练绑定在 tune_mm_llm 分支里,没有读取这个独立开关。修复后还需要打印可训练参数名,确认实际状态与配置一致。配置文件写“开启”不是训练证据。

第二个发生在 DeepSpeed ZeRO[优化器与参数状态分片技术]导出。一个包能够被 from_pretrained() 加载,并不意味着所有权重都有有效值。首次导出的 1,338 个张量中,有 758 个张量的零值比例超过 99%,原始权重在相同画面下能生成动作,导出包却生成重复无效字符。应先修复权重聚合和保存流程,再讨论训练质量。

修正后的适配包包含 615 个可训练张量,约 6.809 亿参数,主文件约 1.36 GB。它需要先加载原始 DualVLN 权重,再覆盖可训练参数,不能把仅含增量参数的目录直接当成完整模型。

接口上,model_path 指向完整原始模型,trainable_params_path 指向增量参数;必要时 processor_path 指向原始模型的图像与文本处理配置。加载时需检查缺失键和额外键:增量包省略冻结参数可以是预期行为,但额外键必须逐个解释。本地曾出现另一评估实现报告一个额外键的情况,不能写成全链路已完全一致。

9. 提交与归档留下什么

提交前先检查压缩包内部名称、任务数量、唯一标识、空轨迹、非有限坐标和轨迹字段。我们保存的结果使用 reference_path 作为轨迹字段,不能因为字段名称像“参考轨迹”就擅自改成其他名字,应以官方序列化契约为准。

比赛测试划分没有本地目标真值时,本地日志中的 not_reach_goal 计数不能直接解释为线上失败数。没有真值的生成检查用于确认轨迹有效,线上回执才给出实际成绩。

归档至少保留代码提交版本、配置、数据清单、模型散列、逐条指标、提交包散列和线上编号。原始场景和第三方模型可以通过官方发布源重新获取;失败的完整权重、重复下载包和可重建缓存通常没有必要长期占用空间。

本文配套的 提交包检查脚本 只使用标准库,检查文件结构和轨迹有效性,不计算导航成功率。在任意已安装 Python 的终端执行:

bashpython code/inspect_submission.py /path/to/submission_overall.zip

预期输出为两侧文件名、任务数量、唯一标识数量、空轨迹数量和压缩包散列。缺少一侧、重复任务或非有限坐标会返回失败状态。只有实际测试包才应要求每侧 150 条,局部调试文件不能直接作为正式提交。

10. 复现来源与许可

官方代码许可与场景数据许可不同。我们读取的比赛仓库说明将代码列为 MIT[宽松软件许可],场景和数据列为 CC BY-NC-SA 4.0[署名、非商业使用、相同方式共享许可]。模型和机器人资产需分别遵循原发布方条款,教程仓库的许可不能覆盖它们。

读完后,可以用四项结果检查自己的复现:数据清单逐条完整;模型实际输入图像正确;权重有效且训练开关真正生效;完整验证与正式提交使用一致的执行链路。这四项稳定以后,才能可靠地讨论模型改进带来的分数变化。