{"record":{"id":"e52bd9a817c05331","repo":"mudler/LocalAI","slug":"antispoofer-predict-called-with-no-models-loaded","errorCode":null,"errorMessage":"Antispoofer.predict called with no models loaded","messagePattern":"Antispoofer\\.predict called with no models loaded","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"backend/python/insightface/engines.py","lineNumber":136,"sourceCode":"        cx1 = max(0, int(cx - new_w / 2.0))\n        cy1 = max(0, int(cy - new_h / 2.0))\n        cx2 = min(src_w - 1, int(cx + new_w / 2.0))\n        cy2 = min(src_h - 1, int(cy + new_h / 2.0))\n\n        cropped = img[cy1 : cy2 + 1, cx1 : cx2 + 1]\n        if cropped.size == 0:\n            cropped = img\n        out_h, out_w = self.INPUT_SIZE\n        return cv2.resize(cropped, (out_w, out_h))\n\n    @staticmethod\n    def _softmax(x: np.ndarray) -> np.ndarray:\n        e = np.exp(x - np.max(x, axis=1, keepdims=True))\n        return e / e.sum(axis=1, keepdims=True)\n\n    def predict(self, img: np.ndarray, bbox: tuple[float, float, float, float]) -> SpoofResult:\n        if not self._sessions:\n            raise RuntimeError(\"Antispoofer.predict called with no models loaded\")\n        accum = np.zeros((1, 3), dtype=np.float32)\n        for session, scale, input_name, output_name in self._sessions:\n            face = self._crop_face(img, bbox, scale).astype(np.float32)\n            tensor = np.transpose(face, (2, 0, 1))[np.newaxis, ...]\n            logits = session.run([output_name], {input_name: tensor})[0]\n            accum += self._softmax(logits)\n        accum /= float(len(self._sessions))\n        real_prob = float(accum[0, self.REAL_CLASS_IDX])\n        is_real = int(np.argmax(accum)) == self.REAL_CLASS_IDX and real_prob >= self.threshold\n        return SpoofResult(is_real=is_real, score=real_prob)\n\n\ndef _build_antispoofer(options: dict[str, str], model_dir: str | None) -> Antispoofer | None:\n    \"\"\"Instantiate an Antispoofer from option keys, or return None.\n\n    Recognised options:\n        antispoof_v2_onnx     — path/filename of MiniFASNetV2 (scale 2.7)\n        antispoof_v1se_onnx   — path/filename of MiniFASNetV1SE (scale 4.0)","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/mudler/LocalAI/blob/44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26/backend/python/insightface/engines.py#L118-L154","documentation":"Raised by the insightface backend's Antispoofer.predict when inference is attempted while self._sessions is empty — no antispoofing ONNX models were loaded at construction time. It is a guard against a None/empty iteration that would otherwise return a zero-probability SpoofResult.","triggerScenarios":"Calling predict() on an Antispoofer instance whose _build_antispoofer step loaded zero ONNX sessions (model files missing at init) or after a failed model load was swallowed, then running face verification on an image with a detected face bbox.","commonSituations":"The MiniFASNet antispoof model files were not installed alongside the insightface pack, a permissions/corrupt-file issue at load time that left _sessions empty, or constructing the engine with antispoof intentionally disabled but still routing faces into predict.","solutions":["Install the antispoof model files (they ship with the insightface backend model packs; see the engine's model manifest).","Check the Antispoofer construction logs for swallowed load errors and fix the underlying file/permission problem.","If antispoofing is not desired, skip the predict() call (treat result as unknown) instead of invoking an unarmed spoffer.","Reinstall the insightface pack: local-ai models install insightface-<pack>."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"spoof = _build_antispoofer(options, model_dir)\nif spoof is not None and not spoof._sessions:\n    logger.warning(\"antispoof armed but no sessions; predict() will raise\")","typeGuard":"def antispoofer_armed(spoofer) -> bool:\n    return spoofer is not None and bool(getattr(spoofer, \"_sessions\", None))","tryCatchPattern":"try:\n    result = antispoofer.predict(img, bbox)\nexcept RuntimeError as e:\n    if \"no models loaded\" in str(e):\n        logger.warning(\"antispoof unavailable; treating score as unknown\")\n        result = None  # caller marks liveness indeterminate\n    else:\n        raise","preventionTips":["Verify antispoof ONNX files exist right after installing the insightface pack.","Fail engine construction loudly when antispoof models fail to load instead of leaving it unarmed.","Gate predict() on a session-count check so unarmed spoofers report 'unknown' rather than raise."],"tags":["insightface","face-recognition","antispoofing","model-loading"],"backgroundTag":null,"analyzedSha":"44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26","analyzedAt":"2026-08-15T10:13:50.291Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}