具身操作 Benchmark 深度教程长文版 · 一章一页 · VLA-Harness · D58

总览 / VLA-Harness · D58

vla-eval:模型、环境、协议三解耦的评估矩阵

18 Benchmark × 十余模型适配器:编排、聚合、复现与榜单全文。

接近原文长文版仅排版加工 · 未删减压缩VLA-Harness · D58

What this is

可以。vla-evaluation-harness(命令名 vla-eval)是一个面向 Vision-Language-Action(VLA)模型的统一评估框架,目标是把模型、机器人仿真环境和评估协议解耦:模型只需接入一次,Benchmark 只需适配一次,就可以自动组合成跨模型、跨任务集、跨仿真器的评估矩阵。

项目当前已经覆盖 18 个左右的机器人仿真 Benchmark、十多个模型服务适配器,并提供复现实验、排行榜、Docker 隔离、并行评估和训练中评估等能力。

Stack

  • 语言: Python 为主,辅以 Shell、JavaScript、CSS
  • 运行时: Python 3.8+,推荐 Python 3.11
  • 核心通信: WebSocket + msgpack
  • 环境隔离: Docker,也支持 Charliecloud
  • 异步与服务: anyio、websockets
  • 配置与结果: YAML/OmegaConf、JSON、SQLite
  • 模型与图像处理: NumPy、Pillow、imageio/ffmpeg

How it's organized

src/vla_eval/
  cli/              vla-eval serve/run/test/merge 等命令
  benchmarks/       各类仿真 Benchmark 适配器
  model_servers/    VLA 模型服务适配器
  runners/          同步和实时 EpisodeRunner
  protocol/         WebSocket + msgpack 协议
  results/          Episode、Task、Benchmark 级结果聚合和合并
  orchestrator.py   评估任务编排、分片、错误隔离
  connection.py     Benchmark 到 Model Server 的连接与重连
  recording.py      SQLite 轨迹、步骤和视频记录
  tracking.py       wandb/trackio 指标上报
  render.py         GPU/CPU 渲染后端
  specs.py          图像、状态、语言、动作等模态规格

configs/
  benchmarks/       Benchmark YAML 配置
  model_servers/    模型服务 YAML 配置

docker/
  Dockerfile.*      每个仿真 Benchmark 的独立环境镜像

docs/
  architecture.md   系统架构和通信协议
  reproductions/    模型分数复现报告
  tuning-guide.md   并行评估吞吐调优
  render-backends.md GPU/CPU 渲染说明
  runtimes.md       Docker/Charliecloud 运行方式

leaderboard/
  benchmarks/       各 Benchmark 的标准任务、指标和聚合规则
  scripts/           排行榜数据生成与校验

experiments/
  bench_demand.py   测量环境侧吞吐
  bench_supply.py   测量模型侧吞吐

examples/
  pusht_train_eval/ 训练过程中调用 vla-eval 评估的完整示例

运行链路: Orchestrator 读取 YAML 配置,启动 Benchmark 和 EpisodeRunner;Benchmark 通常运行在 Docker 容器内,模型服务运行在宿主机或独立进程中。两者通过 WebSocket/msgpack 传输 observation 和 action,最终由 ResultCollector 按 episode → task → benchmark 三级聚合结果。

四个维度介绍

1. 任务集:覆盖哪些任务和 Benchmark

项目的任务集不是单一数据集,而是一组机器人操控仿真评估协议。

主要已集成 Benchmark

Benchmark主要评估内容
LIBERO常见桌面机器人操作任务,包括 Spatial、Object、Goal、Long 等 suite
LIBERO-Plus在相机、机器人、语言、光照、背景、噪声、布局等维度上的鲁棒性
LIBERO-Pro更强调泛化和困难分布的 LIBERO 变体
LIBERO-Mem需要记忆和历史信息的操作任务
CALVIN多阶段、长序列语言条件操作任务
SimplerEnvGoogle Robot 和 WidowX 等机器人平台的视觉操作评估
RoboTwin 2.0多种双臂/单臂操作任务和不同示范设置
RoboCasa / RoboCasa365家庭环境中的长尾操作任务
ManiSkill2基于 SAPIEN 的通用机器人操作任务
DuoBench双臂协作任务
RoboMME更全面的多任务、多环境 VLA 评估
Kinetix基于状态输入的控制任务,常用于实时控制研究
MolmoSpaces-Bench空间理解和机器人操作任务
VLABench多样化视觉语言机器人操作任务
MIKASA-Robo记忆、颜色、拦截和 ShellGame 等任务
RoboCerebra机器人操作和认知能力测试
RLBench基于 CoppeliaSim 的视觉操控任务
BEHAVIOR-1K家庭活动和复杂长期任务
RoboDojo双臂 ARX-X5 机器人、Isaac Sim 环境下的任务

README 中的支持矩阵区分三种状态:

  • ✓: 已完成至少一次分数复现;
  • ◇: 已完成集成,但还没有完成首次复现;
  • ·: 计划支持。

因此,“已支持”不等于“已经验证了所有模型和所有任务组合”。

任务配置方式

每个 Benchmark 通常通过 YAML 指定任务 suite、episode 数量、最大步数和随机种子。例如 LIBERO 支持:

  • spatial.yaml
  • object.yaml
  • goal.yaml
  • long.yaml
  • 10.yaml
  • all.yaml

Benchmark 适配器实现统一的接口,例如:

  • get_tasks()
  • reset()
  • step()
  • make_obs()
  • check_done()
  • get_step_result()

因此新增任务集时,主要工作是编写适配器、Docker 镜像和配置文件,而不需要重新实现模型通信或结果聚合逻辑。


2. 引擎 & 本体:使用哪些仿真器和机器人形态

这里可以分为“仿真引擎”和“机器人本体/平台”。

仿真引擎

仿真器/环境对应 Benchmark
MuJoCoLIBERO、部分 RoboCasa、MIKASA-Robo 等
SAPIENManiSkill2、部分机器人操作环境
CoppeliaSimRLBench
Isaac SimRoboDojo 等大型仿真环境
OmniGibsonBEHAVIOR-1K
PyBullet / 其他专用环境部分 RoboTwin 和专项 Benchmark
Kinetix 环境Kinetix 状态控制任务

项目将每个 Benchmark 的依赖封装进单独 Docker 镜像,例如:

ghcr.io/allenai/vla-evaluation-harness/libero
ghcr.io/allenai/vla-evaluation-harness/calvin
ghcr.io/allenai/vla-evaluation-harness/maniskill2
ghcr.io/allenai/vla-evaluation-harness/robocasa
ghcr.io/allenai/vla-evaluation-harness/robotwin
ghcr.io/allenai/vla-evaluation-harness/robodojo

这样可以避免不同仿真器之间的 Python、CUDA、MuJoCo、SAPIEN 或图形库依赖冲突。

机器人本体和平台

项目并不把所有机器人强行抽象成同一个硬编码格式,而是通过 observation/action spec 和模型服务适配器处理差异。涉及的平台包括:

  • LIBERO 机械臂
  • WidowX
  • Google Robot
  • Franka
  • ARX-X5 双臂机器人
  • RoboTwin 中的单臂和双臂平台
  • CALVIN 中的桌面机械臂
  • RoboCasa 中的家庭机器人操作平台

模型服务通过 get_observation_spec()get_action_spec() 声明输入输出,例如:

  • RGB 图像
  • wrist camera 图像
  • 关节状态
  • 末端位姿
  • gripper 状态
  • 自然语言指令
  • 关节动作或末端执行器动作

框架还会处理部分跨 Benchmark 的格式差异,例如:

  • 四元数顺序转换;
  • gripper 开合方向转换;
  • WidowX 与 Google Robot 的状态映射;
  • 图像和状态的 batch 组织;
  • action chunk 的缓存和执行。

GPU 与 CPU 渲染

默认情况下,Benchmark 容器可使用 GPU 进行渲染;如果模型推理占用 GPU,部分 Benchmark 可以使用 CPU 渲染:

vla-eval run \
  --config configs/benchmarks/libero/spatial.yaml \
  --render cpu

但不是所有 Benchmark 都支持 CPU 渲染。Benchmark 会在启动阶段声明自己的 render_backends,不支持时提前报错,而不是运行到中途才失败。


3. 评估指标和分数基线

通用指标层级

框架把结果按以下层级组织:

Episode
  └── Task
        └── Benchmark

每个 episode 通常记录:

  • success
  • completed_subtasks
  • episode 步数
  • 运行时间
  • 是否发生错误
  • failure_reason
  • Benchmark 自定义指标

然后聚合出:

  • mean_success
  • mean_coverage
  • avg_steps
  • num_errors
  • 每个 task 的成功率
  • 每个 suite 或 perturbation 维度的分数

核心结果类型定义在 src/vla_eval/results/collector.py 中,支持 meansummaxmin 等聚合方式。失败 episode 不会被静默丢弃,而是计入失败统计并额外记录 num_errors

不同 Benchmark 的标准分数

项目的 leaderboard 不只是简单地把所有数字求平均,而是为不同 Benchmark 定义了自己的标准协议。

例子:

  • LIBERO: 通常使用各 task success rate 的平均值,常见是 Spatial、Object、Goal、Long 四个 suite。
  • LIBERO-Plus: 对 Camera、Robot、Language、Light、Background、Noise、Layout 七个扰动维度求平均。
  • MIKASA-Robo: 标准协议是五个任务的算术平均:
  • ShellGameTouch
  • InterceptMedium
  • RememberColor3
  • RememberColor5
  • RememberColor9
  • Kinetix: 是 12 个 state-based task 的平均成功率,同时必须记录 inference delay d 和 execution horizon e
  • RoboTwin: 不同论文使用的任务子集可能不同,任务数量从 4 到 17 不等;任务集合不一致时,项目会避免给出可比的总分。
  • RoboDojo: 需要同时注意 task 子集、Memory 维度、episode 数和随机种子,不能把部分结果直接和完整协议比较。

也就是说,项目的“基线”包括两层:

  1. Benchmark 官方或论文协议: 任务集合、episode 数、随机种子、suite 划分和指标定义;
  2. 模型论文报告分数: 用于判断 harness 是否复现了原论文结果。

已有复现分数示例

docs/reproductions/README.md 中提供了模型原论文分数和 harness 复现分数的对照。例如:

模型BenchmarkHarness 复现论文/Checkpoint 报告
OpenVLALIBERO76.2%76.5%
π₀.₅LIBERO97.7%96.9%
OpenVLA-OFTLIBERO96.7%97.1%
GR00T N1LIBERO94.9%97.0%
X-VLALIBERO97.4%98.1%
DB-CogACTLIBERO94.7%94.9%
Qwen3-OFTLIBERO96.8%97.8%
π₀.₅(LeRobot)LIBERO100%99.0%
MolmoAct2(LeRobot)LIBERO97.0%98.0%
MME-VLA π₀.₅RoboMME25.5%22.7%
MolmoBotMolmoSpaces-Bench57.0%57.7%

项目用状态标记复现质量:

  • ✅: 在 95% binomial confidence interval 内;
  • 🟡: 超出置信区间,但差距不超过 5 个百分点;
  • 🔧: 仍在进行中,或存在已知原因导致差距较大;
  • ⬜: 尚未尝试。

因此,这个仓库不仅提供“跑分工具”,还提供了一个用于检查论文结果是否可复现的基线体系。需要注意,代码搜索结果可能受 GitHub 返回数量限制,完整代码结果可在 GitHub Code Search 中查看。


4. Harness 做了什么优化

这是这个项目相比“分别运行每个 Benchmark 脚本”的核心价值。

4.1 模型与环境解耦

模型服务和仿真环境分离:

模型服务器(GPU/宿主机)
        │
        │ WebSocket + msgpack
        ▼
Benchmark 容器(仿真器/环境)

好处是:

  • 模型依赖和仿真器依赖互不污染;
  • 同一个模型可以服务多个 Benchmark;
  • 同一个 Benchmark 可以接入多个模型;
  • 通过 Docker 固定环境版本;
  • 模型和环境可以位于不同进程甚至不同机器。

4.2 Episode 级错误隔离

某个 episode 失败时,不会直接终止整个评估:

  • action timeout:当前 episode 失败,继续下一个;
  • WebSocket 断开:尝试重连;
  • reset()step() 异常:重建环境;
  • 协议错误:记录失败原因;
  • 最终结果中保留 failure_reasonnum_errors

这对于数千 episode 的长时间评估非常重要。

4.3 两层并行:环境并行 + 推理并行

项目通过两种方式提升吞吐:

  1. Episode sharding:(task, episode) 工作项分配到多个独立进程;
  2. Batch inference: 模型服务器将多个 observation 合并成一个 GPU forward。

README 报告的 LIBERO + DB-CogACT 示例:

指标顺序执行并行执行
Episode 数2,0002,000
GPU1× H1001× H100
Wall-clock约 14 小时约 18 分钟
Throughput约 11 obs/s约 486 obs/s
加速比约 47×

使用方式:

./scripts/run_sharded.sh \
  -c configs/benchmarks/libero/spatial.yaml \
  -n 50

模型端则可以配置:

args:
  max_batch_size: 16
  max_wait_time: 0.05

项目还提供 experiments/bench_demand.pyexperiments/bench_supply.py,分别测量:

  • 环境侧需求吞吐量 λ
  • 模型侧供给吞吐量 μ

并根据二者选择 shard 数、batch size 和等待时间。

4.4 Action chunking

很多 VLA 模型一次 forward 会输出一段 action chunk,而不是单个动作。PredictModelServer 会自动管理:

  • action chunk 缓存;
  • chunk_size
  • action ensemble;
  • newest / average / EMA 等动作融合方式。

这样可以减少 GPU forward 次数,特别适合 π₀、X-VLA、CogACT 等模型。

4.5 同时支持同步和实时评估

框架把:

  • Benchmark: 定义环境、任务、状态和成功条件;
  • EpisodeRunner: 定义执行方式、时序和推理策略。

因此同一个 Benchmark 可以使用:

  • SyncEpisodeRunner:等待模型返回 action;
  • Async/Live EpisodeRunner:环境按真实时间推进,模型异步返回 action。

实时模式支持 hold policy,例如模型来不及返回 action 时:

  • 重复上一动作;
  • 输出零动作;
  • 使用自定义补偿策略。

这使得评估不仅衡量“最终成功率”,还可以衡量模型推理延迟对控制效果的影响。

4.6 记录、合并与可观测性

评估结果默认写入 SQLite:

recording-<eval_id>.sqlite

记录内容包括:

  • episode 结果;
  • step-level trajectory;
  • evaluation metadata;
  • 可选视频;
  • Benchmark 和模型共同写入的 step 字段。

多个 shard 可以并发写入同一个数据库,之后执行:

vla-eval merge \
  -c configs/benchmarks/libero/spatial.yaml

再生成:

  • 每 episode JSONL;
  • Benchmark aggregate JSON;
  • 轨迹和视频文件。

同时支持:

  • Weights & Biases;
  • Trackio;
  • eval_id 关联 live run 和 merge run;
  • 训练过程中周期性评估。

4.7 训练中评估

除了 CLI,项目还提供 Python API:

import vla_eval

results = vla_eval.evaluate(
    MyModelServer(model),
    "configs/benchmarks/libero/smoke_test.yaml",
)

examples/pusht_train_eval/ 展示了如何在训练脚本中:

  1. 创建模型;
  2. 启动 in-process model server;
  3. 每隔若干训练步运行评估;
  4. 读取 mean_success 和其他指标;
  5. 继续训练。

这让 evaluation 从“训练结束后单独运行”变成了训练循环中的反馈信号。

4.8 可复现和工程化优化

项目还做了这些工程化处理:

  • Benchmark 环境 Docker 化;
  • 配置文件完整保存到结果中;
  • 固定随机种子;
  • 明确的模型 observation/action spec;
  • lazy import,避免无关仿真器依赖在启动时加载;
  • health check 和 HELLO handshake;
  • WebSocket 自动重连和指数退避;
  • watchdog 检测卡死的 Benchmark;
  • 支持无 Docker daemon 的 Charliecloud;
  • CPU rendering 释放 GPU 给模型;
  • vla-eval test 做配置、模型服务和 Benchmark smoke test;
  • vla-eval merge 统一处理多 shard 结果。

How to run it

最小运行流程如下:

pip install vla-eval

启动模型服务:

vla-eval serve \
  --config configs/model_servers/db_cogact/libero.yaml

另一个终端运行 Benchmark:

vla-eval run \
  --config configs/benchmarks/libero/smoke_test.yaml

源码开发环境:

uv sync --python 3.11 --all-extras --dev

make check
make test
make smoke

一句话总结

这个项目的核心不是新增某个机器人 Benchmark,而是提供一个统一的 VLA 评估基础设施层:它把不同仿真器、机器人本体、模型输入输出格式和论文评估协议统一起来,同时通过 Docker 隔离、WebSocket 解耦、分片并行、Batch 推理、实时 runner、SQLite 记录和复现基线,把 VLA 评估从“每篇论文一套脚本”优化成可复用、可扩展、可复现的评估系统。