How to Export Microduck RL Checkpoints: A Complete Guide to ONNX Conversion

The recommended way to export Microduck RL checkpoints is to use the official CLI wrapper scripts/export.py, which converts trained models to ONNX format with the observation normalizer baked directly into the graph.

This guide covers the complete export workflow for the pollen-robotics/microduck_rl reinforcement learning stack. Whether you're preparing a policy for real robot deployment or sharing results, following the official export pipeline ensures your Microduck RL checkpoint maintains full functionality.

Why Use the Official Export Pipeline

Manual ONNX conversion of RL checkpoints often fails because the observation normalizer is excluded from the exported graph. According to the docstring in src/mjlab_microduck/export.py, this omission produces non-functional models on hardware. The official pipeline runner.export_policy_to_onnx (lines 52–57) is the only path that guarantees normalization is preserved.

Additional benefits include:

  • Encapsulated environment setup and device handling
  • Automatic WandB integration for remote checkpoint retrieval
  • Consistency with the publish command for verified policy distribution

Using the Export CLI

The scripts/export.py wrapper provides the simplest interface. It imports mjlab_microduck.export.main, parses arguments, and delegates to run_export.

Basic Export Command

uv run scripts/export.py <TASK_ID> --wandb-run-path <entity/project/run> [--checkpoint <N>]
Parameter Description
TASK_ID Registered task name from mjlab.tasks (e.g., Mjlab-Velocity-Flat-MicroDuck)
--wandb-run-path Full WandB run identifier where the checkpoint was logged
--checkpoint Optional iteration number; uses latest if omitted

Export a Specific Checkpoint

uv run scripts/export.py Mjlab-Velocity-Flat-MicroDuck \
    --wandb-run-path yourname/microduck/1234567890abcdef \
    --checkpoint 3000 \
    --onnx-file my_policy.onnx

This retrieves iteration 3000 from the specified WandB run and writes my_policy.onnx to disk.

Export with Video Recording

uv run scripts/export.py Mjlab-Velocity-Flat-MicroDuck \
    --wandb-run-path yourname/microduck/1234567890abcdef \
    --video \
    --video-length 200 \
    --onnx-file latest_policy.onnx

The --video flag generates a visual verification of the exported policy behavior.

Programmatic Export from Python

For integration into training pipelines or automated workflows, use run_export directly:

from mjlab_microduck.export import run_export, ExportConfig

cfg = ExportConfig(
    onnx_file="policy.onnx",
    wandb_run_path="yourname/microduck/1234567890abcdef",
    checkpoint=3000,
)
result = run_export("Mjlab-Velocity-Flat-MicroDuck", cfg)
print(f"Exported ONNX to {result.onnx_path}")

The ExportResult object provides provenance data including the source checkpoint path and iteration number.

Understanding the Export Implementation

The core logic resides in src/mjlab_microduck/export.py. The run_export function executes the following sequence:

  1. Environment loading — load_env_cfg(task_id, play=True) initializes the environment in play mode
  2. Configuration retrieval — load_rl_cfg fetches the RL hyperparameters
  3. Checkpoint resolution — get_wandb_checkpoint_path downloads from WandB or locates local logs/ files
  4. Runner instantiation — load_runner_cls creates an OnPolicyRunner and loads weights
  5. ONNX export — runner.export_policy_to_onnx bakes in the normalizer
  6. Metadata attachment — attach_metadata_to_onnx embeds provenance information

Key Files Reference

File Purpose
src/mjlab_microduck/export.py Core export implementation with run_export and ONNX handling
scripts/export.py CLI entry point wrapping export.main
AGENTS.md Export command documentation and usage overview
README.md Quick-start examples for common workflows

Summary

  • Use scripts/export.py as the primary interface for converting Microduck RL checkpoints to ONNX
  • Always include --wandb-run-path to resolve checkpoint locations automatically
  • Specify --checkpoint for reproducible exports or omit for the latest iteration
  • Call run_export programmatically when integrating into automated pipelines
  • Verify normalizer inclusion by using the official pipeline—manual conversion risks deployment failure

Frequently Asked Questions

Where is the observation normalizer stored in the exported model?

The normalizer is baked into the ONNX graph itself through runner.export_policy_to_onnx in src/mjlab_microduck/export.py. This ensures the exported model performs identically to the training runner without requiring external normalization files.

Can I export checkpoints stored locally instead of on WandB?

Yes. The get_wandb_checkpoint_path function in src/mjlab_microduck/export.py falls back to local logs/ directories when WandB paths are unavailable. Use the same CLI syntax—the resolver handles both sources transparently.

What task IDs are available for export?

Task IDs correspond to registrations in mjlab.tasks. Common examples include Mjlab-Velocity-Flat-MicroDuck and other MuJoCo-based locomotion tasks. Check your training configuration or the mjlab task registry for the exact identifier used during training.

Why does my manually converted ONNX model behave differently on hardware?

Manual conversion typically omits the observation normalizer, causing input distribution mismatch. The official run_export routine (lines 52–57 of export.py) explicitly preserves this component. Always use the provided export tools for deployment-ready models.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →