> This is the documentation for LibreYOLO 1.6.0. Current version: https://www.libreyolo.com/docs/export/rknn

# RKNN
RKNN is Rockchip's compiled NPU format. LibreYOLO exports an opset-19 ONNX intermediate, compiles it with the RKNN Toolkit2 SDK, and can compare the compiled graph against ONNX Runtime in Toolkit2's host simulator without a board.
Verified against LibreYOLO v1.5.0.

## Install

Compilation needs Rockchip's RKNN Toolkit2, which is distributed as a vendor SDK
under Rockchip's own license and is not a LibreYOLO dependency. There is no
`libreyolo[rknn]` extra, and nothing about this format installs from a single
line.

**LibreYOLO side**

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

**Vendor SDK, installed by you**

```bash
# rknn-toolkit2 is a Rockchip SDK under a separate license. LibreYOLO
# neither bundles nor installs it. x86_64 Linux only; on Windows use
# WSL2 or a Linux container.
#
# Toolkit2 2.3.2 needs setuptools<81 and fails on ONNX 1.19 or newer,
# whose removal of onnx.mapping its compiler still imports.
pip install "setuptools==80.9.0" "onnx==1.18.0"

# Then install the matching rknn-toolkit2 wheel from Rockchip's own
# wheel repository, and confirm it imports:
python -c "import rknn.api; print('rknn-toolkit2 ready')"
```

A board is not needed to compile or to check numerical parity. An RK3588 board is
needed for latency, power and thermal measurements, none of which have been
recorded.

## Export

**Python**

```python
from libreyolo import LibreYOLO

model = LibreYOLO("LibreYOLO9t.pt")

# Writes weights/LibreYOLO9t.rknn and weights/LibreYOLO9t.rknn.metadata.json
path = model.export(format="rknn", name="rk3588", imgsz=640, verify=True)
print(path)
```

**CLI**

```bash
libreyolo export --model LibreYOLO9t.pt --format rknn --name rk3588 \
  --imgsz 640 --verify
```

**Arguments**

```python
model.export(
    format="rknn",
    name="rk3588",     # target platform; target= and target_platform= also work
    imgsz=640,         # must match the variant's recorded canvas
    batch=1,           # any other value raises NotImplementedError
    dynamic=False,     # True raises ValueError
    opset=19,          # any other value raises NotImplementedError
    verify=False,      # True runs the PC simulator and gates on parity
)
```

The request is validated against a list of exact model variants before anything
is compiled, and the canvas is validated too: passing an `imgsz` other than the
one the variant was recorded at raises rather than silently compiling something
untested. LibreYOLO writes an opset-19 ONNX intermediate, compiles it, optionally
simulates it, and removes the intermediate afterwards.

Metadata is a sidecar named `<model>.rknn.metadata.json`, because the RKNN format
has no portable metadata field.

`verify=True` runs Toolkit2's PC simulator inside the same session that compiled
the artifact, compares every output against ONNX Runtime on the same input, and
writes `<model>.rknn.parity.json` with per-output error metrics. The gates are
cosine similarity of at least 0.9999 and normalized RMSE of at most 0.02, applied
to any output that is not already elementwise close; the vendor floating build
lowers internal tensors to half precision, so strict `allclose` does not hold even
when the decoded boxes are stable. A failing run writes
`<model>.rknn.failed.parity.json`, discards the candidate, and leaves any earlier
successful export at that path untouched.

To compare an ONNX artifact you already have, without exporting again:

**Board-free parity against an existing ONNX artifact**

```python
import numpy as np
from libreyolo.export import verify_rknn_simulator_parity

input_tensor = np.random.default_rng(0).standard_normal(
    (1, 3, 640, 640), dtype=np.float32
)
metrics = verify_rknn_simulator_parity(
    "weights/LibreYOLO9t.onnx",
    input_tensor,
    target_platform="rk3588",
    rtol=1e-3,
    atol=1e-4,
    raise_on_failure=False,
)
print(metrics)
```

Toolkit2's simulator runs the in-memory graph produced by `load_onnx` and `build`.
It cannot reload a target-specific `.rknn` file without a board, which is why
`verify=True` does compilation, export and simulation in one session.

## Run the artifact

There is no RKNN entry in `libreyolo/backends`, so `LibreYOLO()` does not load a
`.rknn` file. The compiled artifact is deployed to the board and executed by
Rockchip's own runtime, and preprocessing, decoding, NMS and coordinate rescaling
are the application's responsibility there.

`<model>.rknn.metadata.json` carries the class names, input size, task and target
platform, which is what an application needs to reproduce LibreYOLO's
postprocessing. Ship it alongside the compiled model.

For a host-side check that does not need the board, keep an ONNX artifact at the
same fixed shape and compare it in the simulator, as above.

## Constraints

Four combinations compile, and they are model variants rather than families:

| Variant | Task | Canvas | Target |
|---|---|---:|---|
| YOLO9-t | detect | 640 | RK3588 |
| YOLO9-E2E-t | detect | 640 | RK3588 |
| PicoDet-s | detect | 320 | RK3588 |
| YOLO-NAS-s | detect | 640 | RK3588 |

Everything else is refused before compilation, with the message that RKNN in this
version is limited to the exact simulator-tested detection variants. Compile-only
results for other models exist but are deliberately not presented as support: on
the same measurement run, RF-DETR left two decoder `GridSample` nodes unlowered,
and D-FINE, RT-DETR, RT-DETRv2, RT-DETRv4, DEIM, DEIMv2 and EC compiled and
simulated with decoded outputs that were materially wrong.

Batch 1, static shapes, opset 19. `half=True` is rejected, because RKNN does not
expose LibreYOLO's `half` contract, and `int8=True` is rejected until
representative calibration and task-accuracy results exist.

Other Rockchip targets are rejected: `rk3588` is the only validated platform.

For the full family and task grid, see
[the export matrix](/docs/v1.6.0/reference/export-matrix). For one combination:

**Check one family and task before compiling**

```bash
libreyolo formats --family yolo9 --task detect
```
