{"record":{"id":"d88881f3304ed43d","repo":"mudler/LocalAI","slug":"onnx-model-not-found-onnx-path","errorCode":null,"errorMessage":"ONNX model not found: {onnx_path}","messagePattern":"ONNX model not found: (.+?)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"backend/python/speaker-recognition/engines.py","lineNumber":312,"sourceCode":"\nclass OnnxDirectEngine:\n    \"\"\"Run a pre-exported ONNX speaker encoder (WeSpeaker / 3D-Speaker).\"\"\"\n\n    name = \"onnx-direct\"\n\n    def __init__(self, model_name: str, options: dict[str, str]):\n        import onnxruntime as ort  # type: ignore\n\n        # The gallery is expected to have dropped the ONNX file under\n        # the models directory; accept either an absolute path or a\n        # filename relative to _model_path.\n        onnx_path = options.get(\"model_path\") or options.get(\"onnx\")\n        if not onnx_path:\n            raise ValueError(\"OnnxDirectEngine requires `model_path: <file.onnx>` in options\")\n        if not os.path.isabs(onnx_path):\n            onnx_path = os.path.join(options.get(\"_model_path\", \"\"), onnx_path)\n        if not os.path.isfile(onnx_path):\n            raise FileNotFoundError(f\"ONNX model not found: {onnx_path}\")\n\n        providers = options.get(\"providers\")\n        if providers:\n            provider_list = [p.strip() for p in providers.split(\",\") if p.strip()]\n        else:\n            provider_list = [\"CPUExecutionProvider\"]\n        self._session = ort.InferenceSession(onnx_path, providers=provider_list)\n        input_meta = self._session.get_inputs()[0]\n        self._input_name = input_meta.name\n        # Pre-exported speaker encoders come in two shapes:\n        #   rank-2  [batch, samples]          — some 3D-Speaker exports feed raw waveform.\n        #   rank-3  [batch, frames, n_mels]   — WeSpeaker and most Kaldi-lineage encoders\n        #                                        expect pre-computed Kaldi FBank features.\n        # We detect this at load time and branch in embed(), because feeding raw audio\n        # into a rank-3 graph is exactly what triggered\n        # \"Invalid rank for input: feats Got: 2 Expected: 3\".\n        self._input_rank = len(input_meta.shape) if input_meta.shape is not None else 2\n        self._expected_sr = int(options.get(\"sample_rate\", \"16000\"))","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/mudler/LocalAI/blob/44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26/backend/python/speaker-recognition/engines.py#L294-L330","documentation":"OnnxDirectEngine in the speaker-recognition backend requires an ONNX file to instantiate onnxruntime's InferenceSession. The path comes from the `model_path:` (or `onnx:`) option; relative names are resolved against the `_model_path` option (the gallery's models directory). If the resolved path does not exist on disk, __init__ raises FileNotFoundError before any session is created.","triggerScenarios":"Loading a speaker-recognition model whose YAML config has `model_path: speaker.onnx` but the gallery never downloaded the .onnx file into the model directory; passing a bare filename when `_model_path` is empty so the path resolves to `/speaker.onnx`; typo in the filename or the file was deleted/cleaned from the models dir.","commonSituations":"Gallery entry references an ONNX artifact that lives in a different repo subfolder (file lands under a subdirectory, not the dir given by _model_path); model installed via a partial download; option spelled differently (e.g. `onnx_path:` instead of `model_path:`) so an older absolute path option goes stale after the models dir moved.","solutions":["Check that the file actually exists: ls the resolved path printed in the message (it is the joined _model_path + filename).","If the file is elsewhere, set `model_path:` to the absolute path of the .onnx, or move/copy the file into the model's directory referenced by _model_path.","Fix the gallery/model config so the ONNX artifact is downloaded into the models directory (verify the gallery URL and file name match).","If the option key was misspelled, use `model_path: <file.onnx>` (or `onnx:`) in the model options."],"exampleFix":"# before (model YAML)\noptions:\n  model_path: speaker_encoder.onnx   # file not in models dir\n# after — absolute path to the actual artifact\noptions:\n  model_path: /models/speaker-recognition/speaker_encoder.onnx","handlingStrategy":"validation","validationCode":"from pathlib import Path\nimport os\n\ndef validate_onnx_option(options: dict) -> str:\n    p = options.get(\"model_path\") or options.get(\"onnx\")\n    if not p:\n        raise ValueError(\"missing model_path option\")\n    if not os.path.isabs(p):\n        p = os.path.join(options.get(\"_model_path\", \"\"), p)\n    if not Path(p).is_file():\n        raise FileNotFoundError(f\"ONNX file missing: {p}\")\n    return p","typeGuard":null,"tryCatchPattern":"try:\n    engine = OnnxDirectEngine(model_name, options)\nexcept FileNotFoundError as e:\n    logger.error(\"model artifact missing: %s\", e)\n    raise ModelArtifactMissing(options.get(\"model_path\")) from e","preventionTips":["Add a post-install step in the model gallery entry that verifies the .onnx file lands in _model_path.","Log the resolved absolute onnx path at engine construction for fast diagnosis.","Prefer absolute model_path in configs mounted into containers."],"tags":["onnx","speaker-recognition","model-loading","file-not-found","localai"],"backgroundTag":null,"analyzedSha":"44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26","analyzedAt":"2026-08-15T10:13:50.291Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}