Skip to main content

Inspect Robots adapters for I2RT YAM bimanual arms driven by MolmoAct2.

Project description

🦾 inspect-robots-yam

Run Inspect Robots evals on real I2RT YAM bimanual arms driven by MolmoAct2.

CI License: MIT Coverage Built on Inspect Robots

Inspect Robots has two swappable inputs: a Policy (the VLA brain) and an Embodiment (the robot body + world). This package provides both for the YAM + MolmoAct2 stack, so any embodiment-agnostic Inspect Robots task — e.g. all of KitchenBench — runs on real arms:

  • molmoact2 policy — a thin client for MolmoAct2's first-party bimanual-YAM /act server (the model owns the GPU + weights in its own process).
  • yam_arms embodiment — the I2RT joint-position driver, with a hard safety clamp, operator-in-the-loop success, and self-paced control.

Both declare the same 14-D joint-position contract (2 arms × [6 joints + gripper], cameras top/left/right, packed joint_pos state), so Inspect Robots's compatibility check passes with zero errors and zero warnings — verifiable before any motion.

inspect-robots run --task kitchenbench/pour_pasta --policy molmoact2 --embodiment yam_arms

Note: the CLI forwards scalar key=value knobs only — it cannot inject a camera_reader, which hardware runs require. Launch from Python (see Run on hardware) or register your own entry-point factory that bundles the cameras; otherwise yam_arms fails fast with a ConfigError at reset(), before any driver connect or motion.

Install (on the robot/GPU machine)

# Inspect Robots isn't on PyPI yet; uv resolves it (and the optional i2rt driver) from git.
uv pip install "inspect-robots-yam[client,yam] @ git+https://github.com/robocurve/inspect-robots-yam"
  • clientrequests + json-numpy (the /act transport).
  • yam → the I2RT i2rt driver (GitHub-only).

Then download the model weights (needs a Hugging Face token) and start the server, from the MolmoAct2 repo:

huggingface-cli download allenai/MolmoAct2-BimanualYAM
python examples/yam/host_server_yam.py          # serves /act on :8202

Preflight — prove compatibility before any motion

inspect-robots-yam-preflight                                  # dims/semantics/cameras/state
inspect-robots-yam-preflight --task kitchenbench/pour_pasta   # + scene realizability
inspect-robots-yam-preflight --dry-run                        # affirm no motion

A green preflight means action dim (14), control mode (joint_pos), cameras, and state keys all line up. It does not prove the joint values are interpreted the same way — see Safety below.

Run on hardware

You must provide a camera_reader (there is no universal camera API) returning {"top_cam", "left_cam", "right_cam": HxWx3 uint8}. From Python:

from inspect_robots import eval
from inspect_robots.approver import ClampApprover
from inspect_robots_yam import MolmoAct2Policy, YAMEmbodiment, YamConfig

emb = YAMEmbodiment(YamConfig(left_channel="can0", right_channel="can1"),
                    camera_reader=my_camera_reader)
pol = MolmoAct2Policy(server_url="http://127.0.0.1:8202")

(log,) = eval("kitchenbench/pour_pasta", pol, emb,
              approver=ClampApprover(emb.info.action_space))  # defense in depth
print(log.status, log.results.metrics)

At each episode end the embodiment asks the operator (y/N); a yes records termination_reason="success", which KitchenBench's task_success scorer reads. The operator prompts need an interactive terminal — a dead stdin raises EmbodimentFault (the framework's always-halt path). For runs with no operator, set YamConfig(unattended=True) (CLI: -E unattended=true): all operator prompts are skipped and every episode runs to max_steps, scoring as a failure.

Safety

  • Hard clamp backstop. Every command is clipped to YamConfig.joint_low/high inside step(), independent of any Inspect Robots Approver — unclamped model outputs can never reach the motors. Set the arm slots to your real YAM joint limits (the defaults are conservative placeholders: joints ±π, gripper 0–1) — but note the limits are in policy units per the table below: gripper slots 6 and 13 stay normalized 0–1, only slots 0–5 and 7–12 are radians.
  • Use ClampApprover on hardware for a second layer.
  • Zero-gravity handoff jump. The arms connect in zero-gravity mode by default (YamConfig(zero_gravity_mode=True), passed through to the i2rt driver), so the first stiff PD command — homing or the first action — can jump from wherever the arm was idling. Nothing bounds the per-step joint delta yet (tracked as a known issue); stand clear at reset() and prefer a home_pose near the resting pose.
  • Absolute vs. delta joints — verify first. MolmoAct2's YAM actions are treated as absolute joint targets by default. If your checkpoint emits deltas, set YamConfig(joints_are_delta=True) (the embodiment converts to absolute internally so the declared joint_pos stays honest). Inspect Robots's compat check cannot tell these apart — confirm with --dry-run and a single slow jog before running a task.
  • Gripper polarity/trim. The i2rt driver already exposes the YAM gripper as normalized 0–1 in both directions, so the defaults (gripper_open=0.0, gripper_closed=1.0) are an identity map and correct for standard grippers. YamConfig(gripper_open=..., gripper_closed=...) is a polarity/trim remap over that already-normalized range — its main use is a gripper wired with inverted polarity (gripper_open=1.0, gripper_closed=0.0). The remap is a bijection: commands are de-normalized on the way out and observations are re-normalized on the way back, so the model always sees 0–1. Warning: values outside [0, 1] are forwarded on a path i2rt does not clip — avoid them unless you have verified your firmware's behavior.

Configuration

Units — every 14-D vector uses the same layout

joint_low/joint_high, home_pose, actions, and the observed joint_pos state all use policy units:

Slots Meaning Unit
0–5, 7–12 left / right arm revolute joints radians
6, 13 left / right gripper normalized 0–1 (0 = open, 1 = closed)

Hardware gripper units (via gripper_open/gripper_closed) exist only at the driver boundary; nothing you configure here is in hardware gripper units.

YamConfig: left_channel, right_channel, gripper_type (i2rt GripperType enum name, e.g. LINEAR_4310; grippers only — NO_GRIPPER/YAM_TEACHING_HANDLE would break the 14-D packing and are rejected), control_hz, cam_height/width, joint_low/high, home_pose, gripper_open/closed, joints_are_delta, zero_gravity_mode (default True; see Safety), unattended (default False; skip operator prompts). MolmoActConfig: server_url, endpoint, num_steps, timeout_s, camera_order, state_key, cam_height/width.

Scalar knobs are settable from the CLI: inspect-robots run -P server_url=http://gpu:8202 -E left_channel=can0 ....

Development

uv venv && uv pip install -e ".[dev]"     # inspect_robots + kitchenbench from git tags
uv run pre-commit install
uv run pytest --cov                        # 100% coverage required
uv run ruff check . && uv run mypy

The whole suite runs with no hardware, no server, and no stdin — the i2rt driver, cameras, the /act transport, the clock, and operator I/O are all injected. The default hardware seams are excluded from coverage (# pragma: no cover).

Citation

If you use Inspect Robots YAM in your research, please cite it:

@software{inspect-robots-yam,
  author  = {Robocurve},
  title   = {Inspect Robots YAM: Adapters for I2RT YAM bimanual arms},
  year    = {2026},
  url     = {https://github.com/robocurve/inspect-robots-yam},
  version = {0.3.0},
  license = {MIT}
}

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

inspect_robots_yam-0.3.0.tar.gz (36.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

inspect_robots_yam-0.3.0-py3-none-any.whl (21.9 kB view details)

Uploaded Python 3

File details

Details for the file inspect_robots_yam-0.3.0.tar.gz.

File metadata

  • Download URL: inspect_robots_yam-0.3.0.tar.gz
  • Upload date:
  • Size: 36.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for inspect_robots_yam-0.3.0.tar.gz
Algorithm Hash digest
SHA256 c35e1f8ee4ddd4f97a422c718d206a15db5147f5156c0c5e58c7eaa7d00d184b
MD5 5a3bd45b4baa90d076481831c0119dec
BLAKE2b-256 06c518f71f45faa42425de3c3f2443f7204b4b3001b6b30e6504a3179873290b

See more details on using hashes here.

Provenance

The following attestation bundles were made for inspect_robots_yam-0.3.0.tar.gz:

Publisher: release.yml on robocurve/inspect-robots-yam

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file inspect_robots_yam-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for inspect_robots_yam-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5be575d9fa3060b089df23f91f4712f59f72a9b7e1e8cd001ad7c7ea2c6c57c1
MD5 f7e73c3a91e58a166c4d91abc7119773
BLAKE2b-256 28fd1f10ed296d52fa2f18a623e4ff53c3522fbd710dc780d78d9edeab8fe173

See more details on using hashes here.

Provenance

The following attestation bundles were made for inspect_robots_yam-0.3.0-py3-none-any.whl:

Publisher: release.yml on robocurve/inspect-robots-yam

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page