Collect and Train#
Note
Requirements
A CUDA GPU with MUJOCO_GL=egl, the quickstart and policy extras, and a
VLM credential (the collection graph’s perception uses one). Training itself
happens outside GaP with your framework of choice.
examples/collect_and_train closes the
data loop: a verified GaP graph acts as a scripted expert, its rollouts
become a demonstration dataset, an external recipe trains a VLA policy on
them, and the trained policy comes back into GaP as its own policy-skill
node (like the shipped pi05-libero / molmoact-libero skills) — steered by
the same perception that collected the data (Steered Policy).
The whole example is one script,
collect.py, plus the
engine’s gap.connector.collector.DataCollector.
1. Collect demonstrations#
uv sync --extra quickstart --extra policy # sim + perception + openpi client
uv run python examples/collect_and_train/collect.py --episodes 50 --out demos.hdf5 \
--graph examples/libero_quickstart/graph
Flag |
Default |
Meaning |
|---|---|---|
|
|
number of rollouts to record |
|
|
output HDF5 file |
|
|
the expert graph to execute |
|
auto-discovered |
open-robot-skills checkout path |
|
|
LIBERO suite |
|
|
task id within the suite |
The script is short enough to read in full — the core loop is:
import gap
from gap.connector.collector import DataCollector
with gap.connector.sim("libero", task=f"{args.suite}/{args.task}") as conn:
collector = DataCollector(conn, args.out)
try:
for episode in range(args.episodes):
conn.reset(seed=episode + 1) # seeds index the baked variations
collector.start_episode()
result = gap.execute(args.graph, conn, skills=args.skills,
checkpoints="warn")
success, reward = conn.check_success()
collector.end_episode(success=success)
finally:
collector.close()
DataCollector hooks the connector’s step-callback seam, so while an episode
is open it records one synchronized row per control step — no changes to the
graph or the executor. Each episode resets to a fresh baked variation
seed (deterministic initial states, not RNG), runs the expert graph under
checkpoint warnings, and tags the episode with
the simulator’s own success verdict from conn.check_success().
2. The HDF5 dataset#
DataCollector writes a flat, append-only layout:
/observations/<camera>_rgb uint8 [N, H, W, 3]
/observations/state float32 [N, dof+1] (arm joints + gripper)
/actions float32 [N, A] (zero-padded to max A)
/rewards float32 [N]
/dones bool [N]
/episode_ends int64 [E] (exclusive end index per episode)
/episode_success bool [E]
This maps 1:1 onto a LeRobot dataset: /observations/<camera>_rgb becomes
observation.images.<camera>, /observations/state becomes
observation.state, /actions becomes action, and
episode_index / frame_index columns are derived by binning row indices
with /episode_ends.
3. Convert and train (external)#
Convert with a small custom LeRobot adapter over the layout above, filter
to episode_success == True episodes, then train with your recipe of
choice — e.g. LeRobot ACT/diffusion
baselines, or openpi
fine-tuning (pi05 configs). GaP takes no position on the trainer: it only
needs the result behind a websocket policy server.
Tip
The collection script prints kept (successful episodes) as it runs.
Because the expert graph is verified and the simulator scores every episode,
filtering to successes is a one-liner at conversion time rather than a manual
review pass.
4. Serve and run the trained policy#
A shipped policy skill auto-boots its preset, so a steered graph referencing
pi05-libero / molmoact-libero needs nothing extra; to run one server by
hand:
uv run gap policy serve pi05-libero --port 9100
For your own checkpoint, the cleanest path is to package it as its own
policy-skill bundle (subclass gap.runtime.policy_skill.PolicyLoopSkill with
its own preset). For a quick one-off, reference it from the graph by a name and
override that name in the config’s policies: block with a start_cmd that
carries a {port} placeholder:
policies:
my_policy:
start_cmd: "python serve_my_policy.py --checkpoint ckpt/ --port {port}"
Then run it inside a steered graph:
MUJOCO_GL=egl uv run gap run examples/steered_policy/graph_loop \
--sim libero_object_all_variance/0
The steered graph hovers above the perceived object and hands control to your policy — and the hand-off pose matches the distribution this collection script produced, because both use the same OBB perception and approach.
Next steps#
Steered Policy — the hybrid graphs that run the trained policy, and their hand-off tuning.
Policies — serving presets, custom servers, and the policy registry.
Benchmark Grids — score the trained policy as the
policy_only/llm_plus_policybenchmark modes.