immich-app/immich · error · RuntimeError

Failed to load RKNN model

Error message

Failed to load RKNN model

What it means

Raised by init_rknn() when RKNNLite.load_rknn(model_path) returns a non-zero code. By this point is_available is True and an RKNNLite() object was constructed; the failure is specific to loading the .rknn file — the file is missing, unreadable, corrupt, or its format/version is incompatible with the installed RKNNLite runtime.

Source

Thrown at machine-learning/immich_ml/sessions/rknn/rknnpool.py:48

soc_name = None
is_available = False
try:
    from rknnlite.api import RKNNLite

    soc_name = get_soc("/proc/device-tree/compatible")
    is_available = soc_name is not None
except ImportError:
    log.debug("RKNN is not available")


def init_rknn(model_path: str) -> "RKNNLite":
    if not is_available:
        raise RuntimeError("rknn is not available!")
    rknn_lite = RKNNLite()
    rknn_lite.rknn_log.logger.setLevel(logging.ERROR)
    ret = rknn_lite.load_rknn(model_path)
    if ret != 0:
        raise RuntimeError("Failed to load RKNN model")

    if soc_name in RKNN_COREMASK_SUPPORTED_SOCS:
        ret = rknn_lite.init_runtime(core_mask=RKNNLite.NPU_CORE_AUTO)
    else:
        ret = rknn_lite.init_runtime()  # Please do not set this parameter on other platforms.

    if ret != 0:
        raise RuntimeError("Failed to initialize RKNN runtime environment")

    return rknn_lite


class RknnPoolExecutor:
    def __init__(
        self,
        model_path: str,
        tpes: int,
        func: Callable[["RKNNLite", list[NDArray[np.float32]]], list[NDArray[np.float32]]],

View on GitHub (pinned to 199723261c)

Solutions

  1. Confirm the .rknn file exists at the exact model_path in the error and is non-empty; re-download if missing/truncated.
  2. Match the RKNNLite runtime version to the RKNN-Toolkit2 version that produced the model (regenerate the .rknn with the matching toolchain).
  3. Verify the process can read the file (permissions, SELinux/AppArmor labels).
  4. Check that model_prefix resolves correctly: rknnpool expects rknpu/<soc>/model.rknn for your SoC.
  5. Call clear_cache() and re-download to discard a corrupt local copy.

Example fix

# before
# .rknn built with rknn-toolkit2 v1.6, runtime is v2.x -> load_rknn returns non-zero
session = RknnSession(Path('/models/model.rknn'))  # RuntimeError: Failed to load RKNN model

# after
# regenerate the model with the toolchain matching the installed rknnlite runtime
rknn = RKNN()
rknn.config(mean_values=[[0,0,0]], std_values=[[255,255,255]], target_platform='rk3588')
rknn.load_onnx(model_onnx='model.onnx')
rknn.build(do_quantization=False)
rknn.export_rknn('/models/model.rknn')
session = RknnSession(Path('/models/model.rknn'))
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
from os.path import isfile

def validate_rknn_model_file(model_path: str) -> None:
    if not isfile(model_path):
        raise FileNotFoundError(f"{model_path} does not exist")
    p = Path(model_path)
    if p.stat().st_size == 0:
        raise ValueError(f"{model_path} is empty; re-download or regenerate")
    if p.suffix != '.rknn':
        raise ValueError(f"{model_path} is not a .rknn file")

# call before constructing RknnSession:
validate_rknn_model_file(model_path)

Type guard

from pathlib import Path

def is_loadable_rknn_file(model_path: str) -> bool:
    p = Path(model_path)
    return p.is_file() and p.suffix == '.rknn' and p.stat().st_size > 0

Try / catch

try:
    session = RknnSession(model_path)
except RuntimeError as e:
    if 'Failed to load RKNN model' in str(e):
        log.error("RKNN rejected %s; re-downloading and retrying once", model_path)
        Path(model_path).unlink(missing_ok=True)
        redownload(model_path)
        session = RknnSession(model_path)
    else:
        raise

Prevention

When it happens

Trigger: Constructing RknnPoolExecutor (via RknnSession) for a .rknn file that does not exist at model_path, is truncated, was converted with a different RKNN-Toolkit2 version than the runtime supports, or is unreadable due to permissions. load_rknn is called once per worker thread.

Common situations: Wrong model_prefix path (soc_name mismatch in rknpu/<soc>/model.rknn); partial download of the .rknn file; RKNN-Toolkit2 / rknnlite runtime version skew (e.g. model built for rknn-toolkit2 v1.x loaded by runtime v2.x); file permissions blocking the process; bit-flip corruption on the volume.

Related errors


AI-assisted analysis of immich-app/immich@199723261c (2026-08-12). Data as JSON: /api/errors/2e609fcf9e03306a. Report an issue: GitHub.