{"record":{"id":"2e609fcf9e03306a","repo":"immich-app/immich","slug":"failed-to-load-rknn-model","errorCode":null,"errorMessage":"Failed to load RKNN model","messagePattern":"Failed to load RKNN model","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"machine-learning/immich_ml/sessions/rknn/rknnpool.py","lineNumber":48,"sourceCode":"soc_name = None\nis_available = False\ntry:\n    from rknnlite.api import RKNNLite\n\n    soc_name = get_soc(\"/proc/device-tree/compatible\")\n    is_available = soc_name is not None\nexcept ImportError:\n    log.debug(\"RKNN is not available\")\n\n\ndef init_rknn(model_path: str) -> \"RKNNLite\":\n    if not is_available:\n        raise RuntimeError(\"rknn is not available!\")\n    rknn_lite = RKNNLite()\n    rknn_lite.rknn_log.logger.setLevel(logging.ERROR)\n    ret = rknn_lite.load_rknn(model_path)\n    if ret != 0:\n        raise RuntimeError(\"Failed to load RKNN model\")\n\n    if soc_name in RKNN_COREMASK_SUPPORTED_SOCS:\n        ret = rknn_lite.init_runtime(core_mask=RKNNLite.NPU_CORE_AUTO)\n    else:\n        ret = rknn_lite.init_runtime()  # Please do not set this parameter on other platforms.\n\n    if ret != 0:\n        raise RuntimeError(\"Failed to initialize RKNN runtime environment\")\n\n    return rknn_lite\n\n\nclass RknnPoolExecutor:\n    def __init__(\n        self,\n        model_path: str,\n        tpes: int,\n        func: Callable[[\"RKNNLite\", list[NDArray[np.float32]]], list[NDArray[np.float32]]],","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/machine-learning/immich_ml/sessions/rknn/rknnpool.py#L30-L66","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Confirm the .rknn file exists at the exact model_path in the error and is non-empty; re-download if missing/truncated.","Match the RKNNLite runtime version to the RKNN-Toolkit2 version that produced the model (regenerate the .rknn with the matching toolchain).","Verify the process can read the file (permissions, SELinux/AppArmor labels).","Check that model_prefix resolves correctly: rknnpool expects rknpu/<soc>/model.rknn for your SoC.","Call clear_cache() and re-download to discard a corrupt local copy."],"exampleFix":"# before\n# .rknn built with rknn-toolkit2 v1.6, runtime is v2.x -> load_rknn returns non-zero\nsession = RknnSession(Path('/models/model.rknn'))  # RuntimeError: Failed to load RKNN model\n\n# after\n# regenerate the model with the toolchain matching the installed rknnlite runtime\nrknn = RKNN()\nrknn.config(mean_values=[[0,0,0]], std_values=[[255,255,255]], target_platform='rk3588')\nrknn.load_onnx(model_onnx='model.onnx')\nrknn.build(do_quantization=False)\nrknn.export_rknn('/models/model.rknn')\nsession = RknnSession(Path('/models/model.rknn'))","handlingStrategy":"validation","validationCode":"from pathlib import Path\nfrom os.path import isfile\n\ndef validate_rknn_model_file(model_path: str) -> None:\n    if not isfile(model_path):\n        raise FileNotFoundError(f\"{model_path} does not exist\")\n    p = Path(model_path)\n    if p.stat().st_size == 0:\n        raise ValueError(f\"{model_path} is empty; re-download or regenerate\")\n    if p.suffix != '.rknn':\n        raise ValueError(f\"{model_path} is not a .rknn file\")\n\n# call before constructing RknnSession:\nvalidate_rknn_model_file(model_path)","typeGuard":"from pathlib import Path\n\ndef is_loadable_rknn_file(model_path: str) -> bool:\n    p = Path(model_path)\n    return p.is_file() and p.suffix == '.rknn' and p.stat().st_size > 0","tryCatchPattern":"try:\n    session = RknnSession(model_path)\nexcept RuntimeError as e:\n    if 'Failed to load RKNN model' in str(e):\n        log.error(\"RKNN rejected %s; re-downloading and retrying once\", model_path)\n        Path(model_path).unlink(missing_ok=True)\n        redownload(model_path)\n        session = RknnSession(model_path)\n    else:\n        raise","preventionTips":["Keep RKNN-Toolkit2 (model conversion) and rknnlite (runtime) versions matched; regenerate models on runtime upgrades.","Verify the .rknn file size/hash after download; reject zero-byte or short files.","Confirm the rknpu/<soc>/model.rknn path matches your SoC's model_prefix before loading."],"tags":["rknn","npu","model-loading","rockchip","version-mismatch"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}