Exporting Policies with LEAPP#
This guide covers how to export trained reinforcement learning policies from Isaac Lab using LEAPP (Lightweight Export Annotations for Policy Pipelines). The main goal of the LEAPP export path is to package a policy together with the input and output semantics needed for deployment, so downstream users do not need to reimplement Isaac Lab observation preprocessing, action postprocessing, or recurrent-state handling by hand.
The Isaac Lab LEAPP exporter traces the data flowing between the policy and the simulation,
capturing the operations applied along the way. It also embeds semantic metadata for the exported
policy inputs and outputs. In practice, this makes the exported policy a better fit for Isaac
deployment libraries. Isaac Lab can already consume these exports through
LeappDeploymentEnv.
Note
This export path currently supports manager-based RL environments (ManagerBasedRLEnv)
trained with RSL-RL, RL-Games, skrl, or Stable-Baselines3. Other environments
are not yet supported.
Prerequisites#
This export flow requires leapp, Python >= 3.10, and PyTorch >= 2.6.
leapp is a specialized optional extra (it is not part of --extra all).
Select extras the same way as isaaclab train: add --extra leapp on every
uv run, and add the backend extra that matches your task. --extra makes the
integration available; physics=... selects it for the task:
Newton (kitless):
--extra leapp(no Isaac Sim extra)OV PhysX:
--extra ovphysx,leappwithphysics=ovphysxIsaac Sim PhysX:
--extra isaacsim,leappwithphysics=isaacsim_physx
See Install and run your first task and Optional extras for the full extras model used by training and play.
Why Export with LEAPP#
Running the export script generates a self-contained export directory alongside your checkpoint (or at a custom path). The directory contains:
Exported model files —
.onnx(default) or.ptdepending on the chosen backend.Export metadata — LEAPP records the semantic information and wiring needed by downstream deployment runtimes.
Initial values — a
.safetensorsfile for any feedback state, such as recurrent hidden state or last action.A graph visualization — a
.pngdiagram of the pipeline (can be disabled).
The important outcome for Isaac deployment workflows is that the exported artifact preserves the same dataflow that was used during training and inference inside Isaac Lab. That means downstream consumers can run the policy without reconstructing observation ordering, command wiring, actuator targets, or policy feedback loops themselves.
For a detailed description of LEAPP’s generated artifacts and APIs, refer to the LEAPP documentation.
Exporting a Policy#
Note
Export requires a trained checkpoint. Normally you train a policy first — follow
Install and run your first task and
Reinforcement Learning Workflows — and the export
script then discovers the newest matching local run automatically. To get started
without training, RSL-RL can pass --checkpoint pretrained to download a published
policy for a supported core task and backend combination (availability is limited;
see Pretrained checkpoints).
Use the export script for the RL library that produced the checkpoint. The available script
directories are rsl_rl, rl_games, skrl, and sb3. Export runs headless by default.
Use the same backend extra and physics=... selector that you used for training. For Isaac Sim
Kit launches in non-interactive shells, set the EULA variables so startup does not prompt:
# Newton backend (kitless)
uv run --extra leapp python \
scripts/reinforcement_learning/leapp/<rl_library>/export.py \
--task <TASK_NAME> physics=newton_mjwarp
# OV PhysX backend
uv run --extra ovphysx,leapp python \
scripts/reinforcement_learning/leapp/<rl_library>/export.py \
--task <TASK_NAME> physics=ovphysx
# Isaac Sim PhysX backend
OMNI_KIT_ACCEPT_EULA=Y ACCEPT_EULA=Y uv run --extra isaacsim,leapp python \
scripts/reinforcement_learning/leapp/<rl_library>/export.py \
--task <TASK_NAME> physics=isaacsim_physx
# Newton backend (kitless)
./isaaclab.sh -p \
scripts/reinforcement_learning/leapp/<rl_library>/export.py \
--task <TASK_NAME> physics=newton_mjwarp
# OV PhysX backend
./isaaclab.sh -p \
scripts/reinforcement_learning/leapp/<rl_library>/export.py \
--task <TASK_NAME> physics=ovphysx
# Isaac Sim PhysX backend
OMNI_KIT_ACCEPT_EULA=Y ACCEPT_EULA=Y ./isaaclab.sh -p \
scripts/reinforcement_learning/leapp/<rl_library>/export.py \
--task <TASK_NAME> physics=isaacsim_physx
:: Newton backend (kitless)
uv run --extra leapp python scripts\reinforcement_learning\leapp\<rl_library>\export.py ^
--task <TASK_NAME> physics=newton_mjwarp
:: OV PhysX backend
uv run --extra ovphysx,leapp python scripts\reinforcement_learning\leapp\<rl_library>\export.py ^
--task <TASK_NAME> physics=ovphysx
:: Isaac Sim PhysX backend
set OMNI_KIT_ACCEPT_EULA=Y
set ACCEPT_EULA=Y
uv run --extra isaacsim,leapp python scripts\reinforcement_learning\leapp\<rl_library>\export.py ^
--task <TASK_NAME> physics=isaacsim_physx
:: Newton backend (kitless)
isaaclab.bat -p scripts\reinforcement_learning\leapp\<rl_library>\export.py ^
--task <TASK_NAME> physics=newton_mjwarp
:: OV PhysX backend
isaaclab.bat -p scripts\reinforcement_learning\leapp\<rl_library>\export.py ^
--task <TASK_NAME> physics=ovphysx
:: Isaac Sim PhysX backend
set OMNI_KIT_ACCEPT_EULA=Y
set ACCEPT_EULA=Y
isaaclab.bat -p scripts\reinforcement_learning\leapp\<rl_library>\export.py ^
--task <TASK_NAME> physics=isaacsim_physx
When --checkpoint is omitted, the exporter uses the selected task’s agent configuration to
find the default checkpoint in the newest matching local run. This avoids hardcoding the
experiment directory or training iteration in the command. Pass --checkpoint <PATH_TO_CHECKPOINT>
to export a specific model instead.
For example, to export a Humanoid policy trained with RSL-RL on Isaac Sim PhysX:
OMNI_KIT_ACCEPT_EULA=Y ACCEPT_EULA=Y uv run --extra isaacsim,leapp python \
scripts/reinforcement_learning/leapp/rsl_rl/export.py \
--task Isaac-Humanoid physics=isaacsim_physx
OMNI_KIT_ACCEPT_EULA=Y ACCEPT_EULA=Y ./isaaclab.sh -p \
scripts/reinforcement_learning/leapp/rsl_rl/export.py \
--task Isaac-Humanoid physics=isaacsim_physx
set OMNI_KIT_ACCEPT_EULA=Y
set ACCEPT_EULA=Y
uv run --extra isaacsim,leapp python scripts\reinforcement_learning\leapp\rsl_rl\export.py ^
--task Isaac-Humanoid physics=isaacsim_physx
set OMNI_KIT_ACCEPT_EULA=Y
set ACCEPT_EULA=Y
isaaclab.bat -p scripts\reinforcement_learning\leapp\rsl_rl\export.py ^
--task Isaac-Humanoid physics=isaacsim_physx
By default, the export artifacts are saved in the same directory as the checkpoint. The exported graph is named after the task.
CLI Options#
The export scripts accept the following common LEAPP-specific arguments in addition to backend-specific and AppLauncher arguments:
Argument |
Default |
Description |
|---|---|---|
|
Automatic local discovery |
Path to a specific checkpoint, or |
|
Task name |
Name for the exported graph and output directory. |
|
|
Export backend. Choices: |
|
Checkpoint dir |
Base directory for export output. |
|
|
Number of environment steps to run during the traced rollout. Set to |
|
|
Skip generating the pipeline graph PNG. |
Note
--checkpoint pretrained is supported by the RSL-RL, RL-Games, skrl, and Stable-Baselines3
exporters, but a published artifact is not available for every task and backend combination.
If no matching artifact has been published, the exporter reports that it is unavailable and
exits. Train the task locally and omit --checkpoint for automatic discovery, or pass an
explicit checkpoint path. See Pretrained checkpoints for the publication scope and the
command that lists the targeted task matrix.
How It Works (High Level)#
The export script performs the following steps:
Creates the environment with
num_envs=1and loads the trained checkpoint.Patches the environment for export. This step injects annotations into the environment so that tensor i/o to the pipeline are identified by LEAPP during execution.
Runs a short rollout (controlled by
--validation_steps) with LEAPP tracing active. During this rollout, LEAPP traces all tensor operations in the pipeline and automatically builds an onnx file.Compiles the graph so the exported model and deployment metadata can be consumed by downstream runtimes, and optionally validates that the exported model reproduces the traced outputs.
The patching is transparent to the policy — no changes to your training code or environment configuration are needed.
Warning
LEAPP is designed to support a broad range of model architectures, but the current implementation has a few important limitations:
Dynamic control flow is not supported when the condition depends on runtime tensor values, such as tensor-dependent
if,for, orwhilelogic.Complex slicing is not fully supported. Examples include dynamic masked indexing using multiple traced tensors such as
tensor[traced1, traced2]. Slicing with constant values or with a single traced tensor is supported such astensor[mask]ortensor[1:5].Critical traced operations should avoid unsupported third-party libraries. PyTorch operations are the best-supported path. NumPy conversions inside the traced node can be captured when they do not cross the graph boundary, but external library calls may not be traceable. Warp operations are not supported by this export path.
Verifying an Export#
After export, we recommend validating the result in three ways.
Use LEAPP’s automatic verification on seen traced data.
Inspect the generated graph visualization.
Read the LEAPP log carefully, especially when the export fails or emits warnings.
Automatic Verification on Seen Data#
By default, Isaac Lab asks LEAPP to validate the exported model after compilation. LEAPP does this by replaying the data it already saw during the traced rollout and checking that the exported artifact reproduces the same outputs.
This is a strong first-line check because it is good at catching export-time issues such as:
backend conversion problems
unsupported or incorrectly lowered operators
output shape or dtype mismatches
numerical discrepancies between the original policy and the exported artifact
recurrent or feedback-state handling mistakes that show up during replay
This validation is controlled by --validation_steps. Setting it to a positive value gives
LEAPP rollout data to validate against. Setting it to 0 skips this automatic check, which
is useful for debugging but not recommended for normal export workflows.
Inspect the Graph Visualization#
LEAPP can generate a diagram of the exported pipeline as part of compile_graph(). Even when
automatic verification passes, it is still worth opening the diagram and doing a quick visual
inspection.
This is especially useful for catching structural issues such as:
missing inputs or outputs
unexpected extra nodes
incorrect feedback edges
naming mistakes that make deployment harder to reason about
You can disable the diagram with --disable_graph_visualization, but we recommend keeping it
enabled while developing and validating a new export path.
Inspect the LEAPP Log#
If something breaks, the LEAPP-generated log is usually the best place to determine exactly what happened. Read it closely and pay attention to both hard errors and warnings.
The log is useful for diagnosing issues such as:
export backend failures
warnings about graph construction or validation
missing metadata
unsupported model patterns
file generation problems
In practice, this should be your first stop when the export does not complete or when the output artifacts do not look correct.
Export Backends#
The --export_method argument controls how the policy network is serialized:
onnx-dynamo (default) — Uses
torch.onnx.dynamo_export. Best compatibility with modern PyTorch features.onnx-torchscript — Uses the legacy
torch.onnx.exportpath. May be needed for certain model architectures.jit-script / jit-trace — Produces TorchScript
.ptfiles instead of ONNX.
Recurrent Policies#
LSTM recurrent policies are supported automatically. The export scripts detect actor-side LSTM
state for RSL-RL, RL-Games, skrl, and Stable-Baselines3 policies, register it as LEAPP feedback
state, and ensure it appears in the feedback_flow section of the output YAML. The initial
hidden state values are saved in the .safetensors file. Other recurrent architectures are
not currently supported by these exporters.
Running the Exported Policy in Simulation#
Isaac Lab provides LeappDeploymentEnv for running exported policies back in
simulation without the training infrastructure. This is the Isaac Lab deployment path for
LEAPP-exported policies and is useful for validating that the packaged policy still behaves
correctly when driven through the deployment stack instead of the training stack.
Run the deployment script with the task name and the exported LEAPP .yaml file.
Use the same backend extra pattern as training and export.
By default, Isaac Lab launches headless when no visualization option is selected. If you expect
to see the policy running in a viewport, pass a visualization option such as --viz newton
or --viz kit:
# Newton backend (kitless)
uv run --extra leapp python \
scripts/reinforcement_learning/leapp/deploy.py \
--task <TASK_NAME> \
--leapp_model <PATH_TO_EXPORTED_LEAPP_YAML> \
--viz newton physics=newton_mjwarp
# OV PhysX backend
uv run --extra ovphysx,leapp python \
scripts/reinforcement_learning/leapp/deploy.py \
--task <TASK_NAME> \
--leapp_model <PATH_TO_EXPORTED_LEAPP_YAML> \
--viz kit physics=ovphysx
# Isaac Sim PhysX backend
OMNI_KIT_ACCEPT_EULA=Y ACCEPT_EULA=Y uv run --extra isaacsim,leapp python \
scripts/reinforcement_learning/leapp/deploy.py \
--task <TASK_NAME> \
--leapp_model <PATH_TO_EXPORTED_LEAPP_YAML> \
--viz kit physics=isaacsim_physx
# Newton backend (kitless)
./isaaclab.sh -p \
scripts/reinforcement_learning/leapp/deploy.py \
--task <TASK_NAME> \
--leapp_model <PATH_TO_EXPORTED_LEAPP_YAML> \
--viz newton physics=newton_mjwarp
# OV PhysX backend
./isaaclab.sh -p \
scripts/reinforcement_learning/leapp/deploy.py \
--task <TASK_NAME> \
--leapp_model <PATH_TO_EXPORTED_LEAPP_YAML> \
--viz kit physics=ovphysx
# Isaac Sim PhysX backend
OMNI_KIT_ACCEPT_EULA=Y ACCEPT_EULA=Y ./isaaclab.sh -p \
scripts/reinforcement_learning/leapp/deploy.py \
--task <TASK_NAME> \
--leapp_model <PATH_TO_EXPORTED_LEAPP_YAML> \
--viz kit physics=isaacsim_physx
:: Newton backend (kitless)
uv run --extra leapp python scripts\reinforcement_learning\leapp\deploy.py ^
--task <TASK_NAME> ^
--leapp_model <PATH_TO_EXPORTED_LEAPP_YAML> ^
--viz newton physics=newton_mjwarp
:: OV PhysX backend
uv run --extra ovphysx,leapp python scripts\reinforcement_learning\leapp\deploy.py ^
--task <TASK_NAME> ^
--leapp_model <PATH_TO_EXPORTED_LEAPP_YAML> ^
--viz kit physics=ovphysx
:: Isaac Sim PhysX backend
set OMNI_KIT_ACCEPT_EULA=Y
set ACCEPT_EULA=Y
uv run --extra isaacsim,leapp python scripts\reinforcement_learning\leapp\deploy.py ^
--task <TASK_NAME> ^
--leapp_model <PATH_TO_EXPORTED_LEAPP_YAML> ^
--viz kit physics=isaacsim_physx
:: Newton backend (kitless)
isaaclab.bat -p scripts\reinforcement_learning\leapp\deploy.py ^
--task <TASK_NAME> ^
--leapp_model <PATH_TO_EXPORTED_LEAPP_YAML> ^
--viz newton physics=newton_mjwarp
:: OV PhysX backend
isaaclab.bat -p scripts\reinforcement_learning\leapp\deploy.py ^
--task <TASK_NAME> ^
--leapp_model <PATH_TO_EXPORTED_LEAPP_YAML> ^
--viz kit physics=ovphysx
:: Isaac Sim PhysX backend
set OMNI_KIT_ACCEPT_EULA=Y
set ACCEPT_EULA=Y
isaaclab.bat -p scripts\reinforcement_learning\leapp\deploy.py ^
--task <TASK_NAME> ^
--leapp_model <PATH_TO_EXPORTED_LEAPP_YAML> ^
--viz kit physics=isaacsim_physx
For Direct workflow policies, see the
Direct workflow LEAPP export tutorial.
That guide shows how to add LEAPP annotations to a direct RL environment so it can be
exported with scripts/reinforcement_learning/leapp/rsl_rl/export.py. Direct
workflow policies are not currently supported by scripts/reinforcement_learning/leapp/deploy.py.
Further Reading#
LeappDeploymentEnvAPI reference