# How to Export RF-DETR Model to ONNX Format

> Export RF-DETR models to ONNX format easily. Use the dedicated export pipeline with the export_onnx function for portable ONNX models. Get started now.

- Repository: [Roboflow/rf-detr](https://github.com/roboflow/rf-detr)
- Tags: how-to-guide
- Published: 2026-09-08

---

**RF-DETR provides a dedicated export pipeline that converts PyTorch inference graphs into portable ONNX models using the `export_onnx` function in [`src/rfdetr/export/_onnx/exporter.py`](https://github.com/roboflow/rf-detr/blob/main/src/rfdetr/export/_onnx/exporter.py).**

Exporting an RF-DETR model to ONNX format enables deployment across diverse hardware platforms and inference engines. The Roboflow RF-DETR repository ships with a complete export toolkit that handles graph tracing, optimization, and metadata embedding. This guide covers both programmatic Python API usage and command-line workflows for generating production-ready ONNX files.

## Prerequisites and Installation

ONNX export functionality is packaged as an optional extra to keep the base installation lightweight. Install the required dependencies using the `[onnx]` specifier:

```bash
pip install "rfdetr[onnx]"

```

This command pulls in `onnx`, `onnx-graphsurgeon`, and `polygraphy`, enabling automatic graph simplification and constant-folding optimizations during export.

## Understanding the ONNX Export Architecture

The core export logic resides in **[`src/rfdetr/export/_onnx/exporter.py`](https://github.com/roboflow/rf-detr/blob/main/src/rfdetr/export/_onnx/exporter.py)**, specifically within the **`export_onnx`** function (lines 61-73). This wrapper around `torch.onnx.export` manages the full conversion pipeline:

1. **Tracing** the PyTorch model using dummy input tensors
2. **Writing** the raw ONNX graph to disk
3. **Optimizing** via shape-inference and graph-surgeon (when extras are installed)
4. **Embedding** metadata under the `rfdetr_notes` field

For custom operator handling, the system references **[`src/rfdetr/export/_onnx/symbolic.py`](https://github.com/roboflow/rf-detr/blob/main/src/rfdetr/export/_onnx/symbolic.py)**, which registers RF-DETR-specific symbolic definitions required for ONNX compatibility.

## Method 1: Programmatic Export (Python API)

For integration into training workflows or custom deployment pipelines, use the Python API directly.

### Loading the Pretrained Model

First, instantiate the desired RF-DETR variant and set it to evaluation mode:

```python
from rfdetr import get_model

model = get_model("rfdetr-small", pretrained=True).eval()

```

Available variants include `rfdetr-small`, `rfdetr-medium`, and other configurations supported by the repository.

### Preparing Dummy Input Tensors

Create a tensor matching the model's training resolution for tracing purposes. This tensor is not embedded in the final graph but guides the export process:

```python
import torch

dummy_input = torch.randn(1, 3, 640, 640)  # batch=1, channels=3, height=640, width=640

```

### Executing the Export

Call `export_onnx` with explicit parameter configuration:

```python
from rfdetr.export._onnx.exporter import export_onnx

export_onnx(
    output_dir="onnx_models",
    model=model,
    input_names=["images"],
    input_tensors=[dummy_input],
    output_names=["boxes", "scores", "labels"],
    dynamic_axes={
        "images": {0: "batch"},
        "boxes": {0: "batch"},
        "scores": {0: "batch"},
        "labels": {0: "batch"},
    },
    backbone_only=False,
    opset_version=17,
    variant_name="rfdetr-small",
)

```

**Key parameters:**
- **`output_dir`**: Destination directory for the `.onnx` file
- **`input_tensors`**: List of example tensors for tracing
- **`dynamic_axes`**: Dictionary mapping input/output names to dynamic dimension indices (commonly used for variable batch sizes)
- **`backbone_only`**: Boolean flag; set to `True` to export only the feature extractor, `False` for the full detection head
- **`opset_version`**: ONNX opset version (default is 17)
- **`variant_name`**: Determines the output filename (`{variant_name}.onnx`)

## Method 2: Command-Line Interface

For automation and CI/CD pipelines, use the CLI entry point in **[`src/rfdetr/export/main.py`](https://github.com/roboflow/rf-detr/blob/main/src/rfdetr/export/main.py)**:

```bash
python -m rfdetr.export.main \
    --model rfdetr-small \
    --output-dir ./onnx_models \
    --input-size 640 \
    --dynamic-axes \
    --opset 17

```

**CLI-to-API mapping:**
- `--model` maps to `variant_name` (model identifier to load)
- `--output-dir` maps to `output_dir`
- `--input-size` generates the dummy tensor `torch.randn(1, 3, <size>, <size>)`
- `--dynamic-axes` enables batch-dimension flexibility
- `--opset` sets the `opset_version`

## Customizing the ONNX Graph

### Dynamic Axes for Batch Processing

To support variable batch sizes in production environments, configure the `dynamic_axes` parameter. This prevents the ONNX exporter from hardcoding the batch dimension to 1:

```python
dynamic_axes={
    "images": {0: "batch_size"},
    "boxes": {0: "batch_size"},
    "scores": {0: "batch_size"},
    "labels": {0: "batch_size"},
}

```

### Opset Versions and Optimizations

The default `opset_version=17` provides broad compatibility with modern inference engines. When the `[onnx]` extras are installed, the exporter automatically applies graph optimizations including:

- **Shape inference**: Propagates tensor dimensions through the graph
- **Constant folding**: Pre-computes static sub-graphs at export time
- **Graph surgeon optimizations**: Simplifies redundant operations via `onnx-graphsurgeon`

## Key Source Files Reference

| File | Purpose |
|------|---------|
| [`src/rfdetr/export/_onnx/exporter.py`](https://github.com/roboflow/rf-detr/blob/main/src/rfdetr/export/_onnx/exporter.py) | Contains the main `export_onnx` implementation (lines 61-73) |
| [`src/rfdetr/export/_onnx/symbolic.py`](https://github.com/roboflow/rf-detr/blob/main/src/rfdetr/export/_onnx/symbolic.py) | Registry for custom ONNX symbolic definitions |
| [`src/rfdetr/export/main.py`](https://github.com/roboflow/rf-detr/blob/main/src/rfdetr/export/main.py) | CLI entry point that wraps the Python API |
| [`src/rfdetr/export/_backend.py`](https://github.com/roboflow/rf-detr/blob/main/src/rfdetr/export/_backend.py) | Shared utilities across export backends (ONNX, TensorRT, etc.) |

## Summary

- **Install extras**: Use `pip install "rfdetr[onnx]"` to obtain optimization libraries
- **Use `export_onnx`**: Located in [`src/rfdetr/export/_onnx/exporter.py`](https://github.com/roboflow/rf-detr/blob/main/src/rfdetr/export/_onnx/exporter.py), this function handles the full conversion pipeline
- **Provide dummy inputs**: Create tensors matching your target resolution (e.g., `640×640`) for accurate tracing
- **Enable dynamic axes**: Map batch dimensions to handle variable input sizes in deployment
- **Choose CLI or Python**: Use `python -m rfdetr.export.main` for automation or `export_onnx()` for programmatic integration

## Frequently Asked Questions

### What dependencies are required for ONNX export?

ONNX export requires the optional `[onnx]` extra, which installs `onnx`, `onnx-graphsurgeon`, and `polygraphy`. Without these, basic export works but graph optimizations and metadata embedding are disabled. Install via `pip install "rfdetr[onnx]"`.

### Can I export only the backbone without the detection head?

Yes. Set the `backbone_only=True` parameter in `export_onnx` or use the `--backbone-only` flag in the CLI. This produces a smaller model suitable for feature extraction workflows rather than end-to-end object detection.

### How do I enable dynamic batch sizes in the exported model?

Pass the `dynamic_axes` dictionary mapping input and output names to their batch dimension indices. For example, map `"images"` to `{0: "batch"}` to allow variable batch sizes at inference time. This is also accessible via the `--dynamic-axes` CLI flag.

### What ONNX opset version should I use for RF-DETR?

The repository defaults to **opset version 17**, which balances feature support with runtime compatibility. Specify `opset_version=17` (or your target version) in the Python API, or use `--opset 17` via CLI. Lower versions may lack support for certain transformer operations used in RF-DETR.