总览 / VLA-Harness · D58
vla-eval:模型、环境、协议三解耦的评估矩阵
18 Benchmark × 十余模型适配器:编排、聚合、复现与榜单全文。
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 | 多阶段、长序列语言条件操作任务 |
| SimplerEnv | Google 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.yamlobject.yamlgoal.yamllong.yaml10.yamlall.yaml
Benchmark 适配器实现统一的接口,例如:
get_tasks()reset()step()make_obs()check_done()get_step_result()
因此新增任务集时,主要工作是编写适配器、Docker 镜像和配置文件,而不需要重新实现模型通信或结果聚合逻辑。
2. 引擎 & 本体:使用哪些仿真器和机器人形态
这里可以分为“仿真引擎”和“机器人本体/平台”。
仿真引擎
| 仿真器/环境 | 对应 Benchmark |
|---|---|
| MuJoCo | LIBERO、部分 RoboCasa、MIKASA-Robo 等 |
| SAPIEN | ManiSkill2、部分机器人操作环境 |
| CoppeliaSim | RLBench |
| Isaac Sim | RoboDojo 等大型仿真环境 |
| OmniGibson | BEHAVIOR-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 通常记录:
successcompleted_subtasks- episode 步数
- 运行时间
- 是否发生错误
failure_reason- Benchmark 自定义指标
然后聚合出:
mean_successmean_coverageavg_stepsnum_errors- 每个 task 的成功率
- 每个 suite 或 perturbation 维度的分数
核心结果类型定义在 src/vla_eval/results/collector.py 中,支持 mean、sum、max、min 等聚合方式。失败 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: 标准协议是五个任务的算术平均:
ShellGameTouchInterceptMediumRememberColor3RememberColor5RememberColor9- Kinetix: 是 12 个 state-based task 的平均成功率,同时必须记录 inference delay
d和 execution horizone。 - RoboTwin: 不同论文使用的任务子集可能不同,任务数量从 4 到 17 不等;任务集合不一致时,项目会避免给出可比的总分。
- RoboDojo: 需要同时注意 task 子集、Memory 维度、episode 数和随机种子,不能把部分结果直接和完整协议比较。
也就是说,项目的“基线”包括两层:
- Benchmark 官方或论文协议: 任务集合、episode 数、随机种子、suite 划分和指标定义;
- 模型论文报告分数: 用于判断 harness 是否复现了原论文结果。
已有复现分数示例
docs/reproductions/README.md 中提供了模型原论文分数和 harness 复现分数的对照。例如:
| 模型 | Benchmark | Harness 复现 | 论文/Checkpoint 报告 |
|---|---|---|---|
| OpenVLA | LIBERO | 76.2% | 76.5% |
| π₀.₅ | LIBERO | 97.7% | 96.9% |
| OpenVLA-OFT | LIBERO | 96.7% | 97.1% |
| GR00T N1 | LIBERO | 94.9% | 97.0% |
| X-VLA | LIBERO | 97.4% | 98.1% |
| DB-CogACT | LIBERO | 94.7% | 94.9% |
| Qwen3-OFT | LIBERO | 96.8% | 97.8% |
| π₀.₅(LeRobot) | LIBERO | 100% | 99.0% |
| MolmoAct2(LeRobot) | LIBERO | 97.0% | 98.0% |
| MME-VLA π₀.₅ | RoboMME | 25.5% | 22.7% |
| MolmoBot | MolmoSpaces-Bench | 57.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_reason和num_errors。
这对于数千 episode 的长时间评估非常重要。
4.3 两层并行:环境并行 + 推理并行
项目通过两种方式提升吞吐:
- Episode sharding: 将
(task, episode)工作项分配到多个独立进程; - Batch inference: 模型服务器将多个 observation 合并成一个 GPU forward。
README 报告的 LIBERO + DB-CogACT 示例:
| 指标 | 顺序执行 | 并行执行 |
|---|---|---|
| Episode 数 | 2,000 | 2,000 |
| GPU | 1× H100 | 1× H100 |
| Wall-clock | 约 14 小时 | 约 18 分钟 |
| Throughput | 约 11 obs/s | 约 486 obs/s |
| 加速比 | 1× | 约 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.py 和 experiments/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/ 展示了如何在训练脚本中:
- 创建模型;
- 启动 in-process model server;
- 每隔若干训练步运行评估;
- 读取
mean_success和其他指标; - 继续训练。
这让 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 评估从“每篇论文一套脚本”优化成可复用、可扩展、可复现的评估系统。