launch_eval.py Reference#
scripts/launch_eval.py
is the recommended entry point for evaluation. It does not run anything itself: it turns
its flags into the environment variables of
scripts/eval/run_eval_pipeline.sh,
the one pipeline that starts the policy server, generates the gym task from the dataset,
serves the episode queue, runs the eval workers and merges the results (see
Policy Evaluation). This page lists every flag it accepts.
Everything runs as local subprocesses, from your working tree as it is:
GPU layout. GPU 0 runs the policy server and GPUs 1..N run the N eval workers (GPUs 0..N-1 under
--replay, which has no server). With fewer GPUs than that, the workers share the visible GPUs round-robin; on a one-GPU workstation the single worker shares GPU 0 with the policy server.--dry-runprints theenv VAR=... bash scripts/eval/run_eval_pipeline.shinvocation instead of running it (--outputwrites it to a file), so you can inspect, edit and rerun it by hand.Submodules. Policy evals need the
maniflow-tb(packagehvla) andmolmo2(packageolmo) submodules, installed by themaniflowextra (see Installation and setup). The pipeline refuses to start if either is missing, or ifmaniflow-tbis not checked out at the commit this checkout pins; fix it withgit submodule update --init maniflow-tb molmo2.--replayneeds neither.
The gym task is generated from --dataset-path: its slug is the dataset directory’s
basename with - replaced by _ (gym id <slug>-v0), unless --task-name overrides it.
Flags are spelled with hyphens (a few also accept an underscore alias), and on/off flags
marked “on” below are turned off with --no-<flag>. Only the flags on this page reach
evaluate.py; there is no pass-through for other evaluate.py flags.
Run profiles#
By default a run uses the default profile (the full queue on one eval GPU);
--smoke-test switches to a small validation profile. Each value can still be
overridden by its own flag:
Setting |
Default |
|
Flag |
|---|---|---|---|
Queue size |
unlimited |
10 episodes |
|
Queue log level |
|
|
|
Parallel envs per eval GPU |
50 |
2 |
|
Eval GPUs |
1 |
1 |
|
Episode timeout (sim seconds) |
30.0 |
3.0 |
|
Output subdirectory |
|
|
|
Pass --num-eval-gpus N to spread the queue over N eval workers (--policy maniflow
and --replay only; see the limits below).
Per-policy defaults#
--policy (or --replay) sets these defaults; the matching flags override them:
Setting |
|
|
|
|---|---|---|---|
High level / low level |
Molmo2 / ManiFlow ( |
symbolic oracle / ManiFlow |
recorded actions |
Policy server |
|
|
none |
|
|
|
none |
|
25 (0 with |
25 |
0 |
|
auto-detected from |
auto-detected |
none |
|
the dataset’s recorded provenance |
same |
same |
|
0.95 |
0.95 |
none |
|
not applied (Molmo2 is the HL) |
on |
not applied |
molmo2_maniflow needs both --model-path (the low-level ManiFlow, also required with
--ll-oracle) and --hl-model-path (the Molmo2 high level). maniflow needs
--model-path. --replay takes no checkpoint.
Limits of molmo2_maniflow. Its server accepts a single eval-client connection and
pre-registers 128 HL-latency slots, so the launcher rejects --num-eval-gpus above 1
and --num-envs above 128. The launcher currently applies this check under --replay
too while --policy is left at its default, so pass --policy maniflow together with
--replay --num-eval-gpus N.
The episode queue#
Every eval episode starts from a recorded episode of --dataset-path. The pipeline starts
scripts/serve_episode_queue.py,
a small HTTP server (port 8001) that loads one setup per dataset episode at startup and
hands them out one at a time. All eval workers pull from this one queue, so each episode
runs exactly once across all GPUs:
LeRobot dataset ──> serve_episode_queue.py ──GET /next──> evaluate.py (worker 1)
│ ──GET /next──> evaluate.py (worker N)
└──GET /size──> run_eval_pipeline.sh (sizing)
What a setup holds. load_setups in utils/episode_dataset.py builds one setup per
episode from the LeRobot parquet columns. Among other things:
the episode’s
pddl_goal, and itshl_promptwhen one is recorded;the robot’s starting joint and gripper positions, and every block’s pose;
the table height or pose, the camera intrinsics, the block size (
cube_scale) and friction;the expert episode’s length and videos, and the frame it starts from (
init_frame_index).
A trimmed example:
{
"episode_id": "ep_000001",
"pddl_goal": "(and (on block_b block_a))",
"robot_joint_positions": [0.0, -0.785, 0.0, -2.356, 0.0, 1.571, 0.785],
"robot_gripper_position": 0.04,
"objects": {
"block_a": {"position": [0.5, 0.0, 0.05], "quaternion": [1.0, 0.0, 0.0, 0.0]}
},
"table_height_delta": 0.0,
"expert_episode_length": 310
}
Whenever environments reset, the worker fetches the next setup for each of them
(EpisodeQueueClient.fetch_reset_states) and writes it into the simulation
(apply_setup). Joints and objects a setup does not list keep their reset values, but
apply_setup raises instead of guessing on a setup/scene mismatch: an object the scene
does not spawn, a missing gripper joint, or a table with neither a recorded pose nor a
height delta. One step later, the worker checks that the simulation state matches the
setup; with --queue-log-level DEBUG the client also logs every fetched setup and every
joint and object write.
Prompt resolution. The language instruction sent to the policy (and logged as the
episode’s prompt) is the setup’s hl_prompt (parquet goal.hl_prompt) when present;
otherwise the setup’s pddl_goal is turned into English by pddl_goal_to_prompt (for
example (and (on block_b block_a)) becomes “put the B block on the A block”). Each environment
gets its own episode’s prompt. For molmo2_maniflow the same string is the Molmo2 task;
--hl-prompt "stack 2 blocks" forces one fixed goal for the whole run.
Which episodes are queued.
--episode-indices(with--allow-duplicate-episodesto repeat an episode) selects the episodes, as0,3,5,10-19or@file.txt(a file of the same entries). The pipeline passes the same selection to task generation and to the queue.--init-after-hl-actionmoves each episode’s start to just after a given high-level action. The robot and block poses, the expert first frames and the--expert-timeout-scalebudget then come from the cut (the remaining expert length).--queue-limitcaps how many are queued.
The queue hands out the longest expert demonstrations first, so the episodes likely to run longest start early and the last stragglers are short ones.
Sizing from the queue. Before starting the workers, the pipeline reads GET /size:
Each worker gets
min(ceil(queue size / --num-eval-gpus), --num-envs)parallel environments, so a small queue does not spawn idle environments.With
--expert-timeout-scale,episode_length_sis raised to cover that multiple of the queue’s longest expert demonstration (expert_seconds_max), so each episode’s own budget is the timeout that binds.
Block-size slots. Block size cannot change after spawn, so when the dataset records a
cube_scale per episode, the generated task spawns one slot per distinct size and the queue
serves each environment only episodes of its slot’s size. A worker spreads its environments
over the slots in proportion to each slot’s queued workload, which it reads from /size
(slot_counts, slot_expert_frames). Every fetch also sends the task’s slot ordering,
and the queue fails if it differs from its own. That catches a task generated from
different --episode-indices than the queue was started with. The queue also refuses to
start if only some of the episodes record a cube_scale.
When the queue drains. An environment whose fetch comes back empty keeps stepping on the task’s default randomization. These “phantom” episodes are never scored or recorded, but they still cost policy inference and physics. A worker stops once all of its environments have drained, and the pipeline prints the queue’s final status at the end.
Endpoints:
GET /next:{"setup": ...}, ornullonce drained. With block-size slots, add?slot=<i>&slot_scales=<s0,s1,...>.GET /size:remaining,total,expert_seconds_max,slot_countsandslot_expert_frames. The queue fails at startup if the dataset’smeta/info.jsonhas nofps, sinceexpert_seconds_maxneeds it.GET /healthz:{"ok": true}.
Dataset requirements#
A run consumes one artifact, the LeRobot dataset at --dataset-path. It is the source of
truth for:
The per-episode setups above. Each needs at least
observation.state.joint_positionandpddl_goal; the other columns (gripper position, block poses, table pose, friction, intrinsics, …) are used when present.The gym task.
generate_task_from_dataset.pyreads the block list from theobservation.state.object_pose.<name>columns and every distinctpddl_goal(quantified, typed goals such as(exists (?b1 ?b2 - block_red) ...)are grounded against the scene’s blocks). Block names resolve to assets by name: a glyph name (block_a..block_z,block_1..block_9) spawns that glyph block from--usd-library, a name inUSD_OVERRIDES(intamp/blocks/template/codegen.py) its USD, and anything else a cuboid coloured by the colour word in its name.The scene. See Dataset scene provenance.
If the dataset has observation.images.* videos, the queue also resolves each episode’s
expert clips, which the W&B episodes table shows next to the rollout.
Dataset scene provenance#
The goal is to rebuild a recorded episode’s scene from the dataset path and episode index
alone. The rebuild has two halves: the scene config (robot, scene preset, table,
cameras, lighting, physics) comes from code and flags, and the per-episode state
(joints, gripper, block poses, table height) comes from the data through apply_setup. If
the scene config does not match the one datagen used, the state lands on the wrong scene,
so eval pins the scene to the dataset’s recorded provenance:
Datagen records
scene_idandrobot_id(per-step columns, ormeta/info.json).generate_task_from_dataset.pybakes them into the generatedenv_cfg.py, andevaluate.py --dataset_pathdefaults the eval robot and scene preset to them (reconcile_env_cfg_with_datasetinutils/dataset_provenance.py).A dataset that records neither, with no
--robot-id/--scene-presetoverride, is rejected rather than run on a possibly wrong scene. An explicit override that disagrees is honoured with a warning; regenerating the task from the dataset (or dropping the override) is the usual fix.The recorded block heights and
table_height_deltaare relative to the datagen preset’s table, soapply_setuprestores the table fromtable_pose(absolute) ortable_height_deltaand fails rather than inferring it from block positions.
What each part of the scene is rebuilt from:
Input |
Recorded in the dataset |
Used by eval |
|---|---|---|
Robot joints and gripper |
|
written at reset |
Block poses |
|
written at reset (the block must be spawned) |
PDDL goal |
|
selects each environment’s goal at reset |
Table height |
|
written at reset |
Block size |
per-episode |
one spawn slot per distinct size |
Block and table friction |
|
written at reset when recorded |
|
per-step columns |
default the eval scene (see above) |
Camera intrinsics |
|
off by default: |
Camera poses and look |
|
checked by scene verification; reproduced only with |
Actuator gains |
|
read by replay and the dataset PD-switch settle (see Dataset Replay) |
Block glyphs and colours |
glyph/colour renders: |
painted with |
Validating dataset loading#
To confirm that the eval scene matches the dataset it was generated from:
scripts/eval/verify_dataset_loading.py(standalone, needs a GPU) applies each requested episode’s setup to a freshly reset environment, all in one Isaac session, and writes a scene diff (table height, blocks present, block and table poses, block sizes, camera intrinsics and pose), first-frame MAE / MSE / SSIM with side-by-side PNGs, and a check of the policy input built from the reset observation. It exits non-zero on any hard mismatch; each camera’s SSIM has a hard floor (--min-first-frame-ssim, default 0.90). Generate the task package first:python scripts/generate_task_from_dataset.py --dataset-path data/datasets/my_dataset --headless python scripts/eval/verify_dataset_loading.py \ --dataset-path data/datasets/my_dataset --task my_dataset-v0 --episode-indices 0 4 \ --obs-mode rgb+state --output-dir runs/verify --headless --enable_cameras
evaluate.py --verify_sceneruns the same scene checks on the first batch of queue setups during a live eval and writesscene_verification.jsonwith comparison PNGs. Hard mismatches are only logged;--verify_scene_strictaborts the run after the report is written. Use strict whenever the numbers will be reported. These two flags are not exposed bylaunch_eval.py.
Evaluating on rendered datasets#
The render stage gives every episode its own look:
its own camera offsets, HDRI sky, table material, lights, exposure and backdrop, recorded in
meta/render_params.json(for a merged dataset, one file per source, reached throughmeta/provenance.json);on glyph and colour renders, its own block letters and colours (
block_variable_map/glyph_map).
By default, eval reproduces only the block identities. Everything else is the single calibrated sim2real scene. Four flags control how much of the recorded look is reproduced:
Flag |
Default |
Effect |
|---|---|---|
|
on |
Fixed sim2real camera intrinsics for every environment; also turns the render replay off. |
|
off |
Reproduce each episode’s camera poses (and the wrist camera’s mount offset), HDRI sky, table material, lights, exposure and backdrop. Does nothing on datasets without |
|
off |
Start episodes in waves, so all environments in a wave share one episode’s lighting (see the caveats below). |
|
on |
Paint each episode’s recorded block letters and colours, and prompt the policy with the goal as rendered. Success is always graded on the source block names. |
To evaluate with the full recorded look:
python scripts/launch_eval.py --policy maniflow \
--model-path data/checkpoints/my_maniflow_run/checkpoints/steps_400000_model.safetensors \
--dataset-path data/datasets/my_rendered_dataset \
--no-use-calibrated-cameras --use-render-params --wave-resets
With --replay, drop --wave-resets, since replay runs a single environment per GPU.
What the launcher checks before it starts anything:
--use-render-paramsneeds--no-use-calibrated-cameras.--wave-resetsneeds--use-render-paramsand more than one environment, so it cannot be combined with--replayor with calibrated cameras.
Caveats:
Lighting is shared by the whole scene. The sky, lights and exposure are one setting for all environments. Without
--wave-resetsthey are set once at the first reset, so with several environments most episodes run under another episode’s lighting.Tiled rendering uses one set of intrinsics. Every environment is drawn with environment 0’s intrinsics, so an environment whose episode recorded different ones reports intrinsics that don’t match its pixels.
A mismatched record is skipped, not fatal. An episode whose render record fails the lookup checks (the episode count per source problem, the front camera position, the table height) runs with nothing applied, and the run carries on.
To check what was applied, look at each episode’s render_replay_status and
block_identity_status (applied or none) in eval_episodes.json; see
Metrics.
HL latency#
The four HL latency flags decouple the high-level conditioning (the oracle for
--policy maniflow, the Molmo2 forward for --policy molmo2_maniflow) from per-step
low-level inference, in milliseconds of sim time
(sim_time_ms = step * step_dt * 1000; see src/toyblocks/serving/hl_latency.py). All
default to 0, which runs the HL on every LL inference with no delay:
K (
--hl-update-interval-ms): invoke the HL at most once per K ms and buffer its output in between.--hl-update-interval-jitter-ms jaddsU(-j, +j)ms to each interval to mimic HL timing variance.M (
--estimated-hl-inference-time-ms): feed the LL the freshest HL output at least M ms old, faking the arm and physics advancing during HL inference.
The Molmo2 server only sees observations at action-chunk boundaries, so a K below
action_horizon * step_dt is a no-op there; the client-side oracle buffer ticks every
control step.
Checkpoints that read the previous front frame. A ManiFlow checkpoint trained with
use_previous_front_frame also takes the aged HL frame as prev_front_rgb. There is no
flag for it: the server advertises the input and the client sends it. M and K then have
to match training: the dataloader pairs each frame with one
n_action_steps * U{1,2,3,4} steps back (n_action_steps is in the checkpoint’s
config.yaml), while the conditioning age cycles within [M, M + K]. So set
M ≈ n_action_steps * step_dt * 1000 and size K so the age reaches about 4x that. Two
settings print a loud startup warning naming the resulting age (neither is fatal, since
each is also how a synchronous HL is configured on purpose):
M = 0: the conditioning frame is the current one at every chunk boundary.K an integer multiple of the action-chunk period (
action_horizon * step_dt * 1000): the HL commits phase-lock with the inferences, so the age is a constant M instead of sweeping[M, M + K). Offset K or add jitter to break the lock.
--save-diagnostic-plots writes hl_conditioning_staleness.png (client-side oracle HL
only), the quickest check of what actually happened: K is the sawtooth period of the
conditioning age and M its floor, and LL calls and HL commits are drawn as event lines.
For the Molmo2 HL, the server-side HL input trace is the equivalent record.
Outputs#
Results go under RUNS_ROOT, which defaults to runs/ in the repository root (set
RUNS_ROOT=/path in the environment of launch_eval.py to change it). Each eval worker
N (seed N, from 1) writes to
runs/<task>-v0/<policy>/<out_subdir>/<problem_id>/seed_<N>/<YYYYmmdd_HHMMSS>_local/
with <policy> from --policy-name (maniflow, molmo2_maniflow or replay by
default), <out_subdir> from the profile or --out-subdir, and <problem_id> from
--problem-id. Besides the evaluate.py outputs
(eval_results.json, eval_episodes.json, the LeRobot dataset, videos), each worker
directory holds launch_params.json (the resolved launch parameters, including the
commit), launch_command.sh (the command line), std_out_err.log (the pipeline log
followed by that worker’s output) and skill_success.json (per-skill success rates from
scripts/skill_success_from_eval_run.py).
At the end, scripts/merge_eval_runs.py
merges the workers into one run directory, runs/<task>-v0/<policy>/<out_subdir>/<problem_id>/<run_id>/,
with every worker’s episodes in one eval_episodes.json, the merged success LeRobot
dataset (moved out of the workers; the failure datasets stay in them) and its own
skill_success.json.
With --wandb, scripts/wandb_consolidate.py
merges every worker into one W&B run named <policy>__<task>-v0__<out_subdir> (needs
WANDB_API_KEY). It carries summary/run_stats_table (one row of headline numbers:
success rates, episode lengths against the expert’s, timeout rate, throughput),
eval/aggregates_table (every metric’s mean, std, min and max),
videos/episodes_with_expert_table (one row per episode, with the expert video next to
the rollout), and, under --save-diagnostic-plots, the debug/policy_inputs_table,
debug/ll_policy_inputs_table and debug/hl_policy_inputs_table debugging tables.
Examples#
# Smoke test of Molmo2 high level + ManiFlow low level (the default policy)
python scripts/launch_eval.py --smoke-test \
--model-path data/checkpoints/my_maniflow_run/checkpoints/steps_400000_model.safetensors \
--hl-model-path data/checkpoints/my_molmo2_run \
--dataset-path data/datasets/my_dataset
# ManiFlow with the high-level oracle, on 4 eval GPUs, logged to W&B
python scripts/launch_eval.py --policy maniflow --num-eval-gpus 4 \
--model-path data/checkpoints/my_maniflow_run/checkpoints/steps_400000_model.safetensors \
--dataset-path data/datasets/my_dataset --wandb
# Molmo2 high level + motion-planned skills (low-level oracle), episodes 0-19 only
python scripts/launch_eval.py --ll-oracle \
--model-path data/checkpoints/my_maniflow_run/checkpoints/steps_400000_model.safetensors \
--hl-model-path data/checkpoints/my_molmo2_run \
--dataset-path data/datasets/my_dataset --episode-indices "0-19"
# Start after every flip or rotate, with a per-episode timeout of 1.5x the expert's
python scripts/launch_eval.py --policy maniflow \
--model-path data/checkpoints/my_maniflow_run/checkpoints/steps_400000_model.safetensors \
--dataset-path data/datasets/my_dataset \
--init-after-hl-action flip,rotate --expert-timeout-scale 1.5
# Replay the dataset's recorded actions (no policy server; one cube scale)
python scripts/launch_eval.py --replay \
--dataset-path data/datasets/my_dataset --episode-indices "0"
# Print the pipeline invocation instead of running it
python scripts/launch_eval.py --dry-run --policy maniflow \
--model-path data/checkpoints/my_maniflow_run/checkpoints/steps_400000_model.safetensors \
--dataset-path data/datasets/my_dataset --output /tmp/eval_run.sh
Flags#
Policy and run mode#
Flag |
Default |
Description |
|---|---|---|
|
|
Policy to evaluate: |
|
off |
Replay the dataset’s recorded actions instead of evaluating a policy: no policy server, each worker runs |
|
none |
With |
|
off |
Use the smoke-test profile above. |
|
off |
Print the |
|
none |
With |
Dataset, task and queue#
See The episode queue for how these flags shape the queue.
Flag |
Default |
Description |
|---|---|---|
|
required |
LeRobot dataset the queue reads its episode setups from and the gym task is generated from. |
|
dataset basename |
Override the gym task slug (a valid Python identifier). |
|
all |
Episodes to queue, e.g. |
|
off |
Allow repeated indices, e.g. |
|
none |
Start each episode at the first frame after every instance of these high-level actions (comma or |
|
profile |
Cap the queue at N episodes. |
|
profile |
Log level of the episode queue server. |
|
|
Glyph asset library for bare block names in task generation; |
Scale and episode budget#
Flag |
Default |
Description |
|---|---|---|
|
profile |
Maximum parallel environments per eval GPU (the pipeline right-sizes it to the queue). At most 128 for |
|
profile (1) |
Eval workers, one per GPU after the policy server’s (GPU 0). Must be 1 for |
|
profile |
Episode timeout in sim seconds. |
|
|
Give each episode its own timeout, this multiple of its expert demonstration’s length (e.g. |
Episode end and scoring#
Flag |
Default |
Description |
|---|---|---|
|
|
What ends an episode before the timeout: |
|
|
A non-target block moving more than 2 cm or 15 deg: |
|
|
Yaw tolerance of the goal’s orientation atoms when judging success. |
|
|
After a play-mode LL releases a block, lift the arm this many metres before the next LL query ( |
ManiFlow model#
Flag |
Default |
Description |
|---|---|---|
|
none |
ManiFlow |
|
|
Model config (for a checkpoint inside |
|
checkpoint’s own |
Normalization |
|
|
Training config merged under the checkpoint’s config; keep it at the pinned |
|
auto-detected |
|
|
|
Seed of the policy server’s action sampling. |
|
off |
Start every sample of a batched inference call from the same flow-matching noise, so identical observations give identical actions ( |
Molmo2 high-level model#
Flag |
Default |
Description |
|---|---|---|
|
none |
Molmo2 checkpoint (required for |
|
per episode |
Force a fixed language goal (e.g. |
|
off |
Never put the previous action in the Molmo2 question (for HL checkpoints trained without it). |
|
server default |
Molmo2 decode budget per answer. |
High-level conditioning#
Flag |
Default |
Description |
|---|---|---|
|
on |
|
|
off |
|
|
off |
|
|
no cap |
With |
|
off |
|
|
|
With |
|
off |
With |
HL latency#
See HL latency for how to choose K and M.
Flag |
Default |
Description |
|---|---|---|
|
|
HL invocation interval K in ms ( |
|
|
Uniform jitter added to each interval. |
|
|
Assumed HL inference time M in ms. |
|
off |
Per-episode side-by-side of the fresh and the aged HL view (needs |
Observations, transform and scene#
See Evaluating on rendered datasets for how the camera, render and block-identity flags work together.
Flag |
Default |
Description |
|---|---|---|
|
per policy |
Observation transform passed to |
|
per policy |
Actions applied per policy chunk. |
|
dataset provenance |
Robot config ( |
|
dataset provenance |
Scene preset ( |
|
0.95 for ManiFlow transforms |
Centre-crop each resized 224x224 input to |
|
off |
ManiFlow transforms only: build |
|
on |
Use the fixed sim2real camera intrinsics; |
|
off |
On a rendered dataset, reproduce each episode’s camera pose, HDRI, table material, lights, exposure and backdrop. Needs |
|
on |
On a glyph/colour-rendered dataset, paint each episode’s recorded block letters and colours and prompt with the recorded goal. Success is graded on the source block names either way. |
|
off |
Start episodes in waves, so each wave shares one episode’s recorded scene lighting. Needs a rendered dataset and |
|
none |
Extra world-frame Z offset (m) for the table and blocks after the queue setup, e.g. |
|
none |
Override the binary gripper close target (radians). |
Recording#
Flag |
Default |
Description |
|---|---|---|
|
on |
Record every rollout as a LeRobot dataset, encoded by sharded writer processes as frames arrive. |
|
run name |
Base name of the merged dataset. |
|
|
Parallel LeRobot writer processes, stitched into one success / failure pair at the end. |
|
|
|
|
off |
Per-episode MP4s from the RGB observations (buffered in RAM, unlike the LeRobot recording). |
|
off |
Record the HL overlay as a video stream in the LeRobot dataset (needs |
|
off |
Per-step metric CSVs in each worker’s output directory; for debugging. |
Diagnostics#
Flag |
Default |
Description |
|---|---|---|
|
off |
Live-rollout diagnostics: policy-input verification panels, the HL staleness plot, and the server-side LL and HL input traces. Also renders every episode’s offline control-diagnostic plots at the end of the pipeline. Implies |
|
off |
Dump the model-ready batch the server saw on step 0 to |
|
off |
Deterministic cuDNN and PhysX enhanced determinism on the server and the workers; slower, and still not bit-for-bit across hardware (see Policy Evaluation). |
W&B and output naming#
Flag |
Default |
Description |
|---|---|---|
|
off |
Log the run to W&B, merging every worker into one run. Also extracts each episode’s expert video for the episodes table. |
|
|
W&B project. |
|
profile |
Output subdirectory under |
|
from |
Policy label used in W&B names and output paths. Currently only the default works: the pipeline also reads this label to choose the policy server, so any other value stops it with |
|
|
|
Deprecated#
Flag |
Description |
|---|---|
|
Rejected with an explanation: |