{"record":{"id":"5649d36e2f62c63f","repo":"ultralytics/ultralytics","slug":"model-has-no-depth-head-with-calibration-buffers","errorCode":null,"errorMessage":"Model has no Depth head with calibration buffers (cal_a/cal_b).","messagePattern":"Model has no Depth head with calibration buffers \\(cal_a/cal_b\\)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"ultralytics/engine/model.py","lineNumber":629,"sourceCode":"        Args:\n            data (str, optional): Dataset YAML providing a labeled split to calibrate against.\n            **kwargs (Any): Extra validation arguments (e.g. ``imgsz``, ``batch``, ``device``, ``split``).\n\n        Returns:\n            (tuple | None): The fitted ``(a, b)``, or ``None`` if fewer than 2 images had valid depth pixels.\n\n        Examples:\n            >>> model = YOLO(\"yolo26s-depth.pt\")\n            >>> model.calibrate(data=\"my_depth_dataset.yaml\")\n            >>> model.save(\"yolo26s-depth-calibrated.pt\")\n        \"\"\"\n        self._check_is_pytorch_model()\n        if self.task != \"depth\":\n            raise ValueError(f\"calibrate() is only supported for depth models (task='depth'), got task={self.task!r}.\")\n        from ultralytics.models.yolo.depth.calibrate import _depth_head, fit_calibration_selective\n\n        if _depth_head(self.model) is None:\n            raise ValueError(\"Model has no Depth head with calibration buffers (cal_a/cal_b).\")\n        args = {**self.overrides, **kwargs, \"mode\": \"val\", \"task\": \"depth\"}\n        if data is not None:\n            args[\"data\"] = data\n        validator = self._smart_load(\"validator\")(args=args, _callbacks=self.callbacks)\n        validator(model=self.model)  # builds the dataloader and reports metrics with the current calibration\n        res = fit_calibration_selective(\n            self.model, validator.dataloader, validator.device, max_depth=validator.data.get(\"max_depth\") or 100.0\n        )\n        if res is None:\n            return None\n        LOGGER.info(\"Call model.save(...) to persist the calibration.\")\n        return res[\"a\"], res[\"b\"]\n\n    def benchmark(self, data=None, format=\"\", verbose=False, **kwargs: Any):\n        \"\"\"Benchmark the model across various export formats to evaluate performance.\n\n        This method assesses the model's performance in different export formats, such as ONNX, TorchScript, etc. It\n        uses the 'benchmark' function from the ultralytics.utils.benchmarks module. The benchmarking is configured using","sourceCodeStart":611,"sourceCodeEnd":647,"githubUrl":"https://github.com/ultralytics/ultralytics/blob/0449ea011cfd6c9a0d50a0bf1043aca5190cd476/ultralytics/engine/model.py#L611-L647","documentation":"Even with task=='depth', calibrate() requires the model's Depth head to carry calibration buffers (cal_a/cal_b); _depth_head() returning None means the head cannot be calibrated and a ValueError is raised. This distinguishes depth models with calibration support from custom depth heads without buffers.","triggerScenarios":"`model.calibrate(...)` on a task='depth' model whose head is a custom Depth implementation without cal_a/cal_b buffers — e.g. a hand-built or modified depth network trained outside the stock yolo26-depth recipes.","commonSituations":"Custom depth architectures labeled task='depth'; checkpoints converted from other frameworks; heads replaced during finetuning.","solutions":["Use a stock Ultralytics depth checkpoint (yolo26s-depth.pt family), which ships a calibratable head.","If the head is custom, add cal_a/cal_b buffers to the Depth head so _depth_head() recognizes it.","Rebuild the model from the official depth YAML and load matching weights."],"exampleFix":"# before\ncustom_depth_model.calibrate(data='depth.yaml')  # ValueError: no cal_a/cal_b\n\n# after\nYOLO('yolo26s-depth.pt').calibrate(data='depth.yaml')","handlingStrategy":"validation","validationCode":"from ultralytics.models.yolo.depth.calibrate import _depth_head\nif _depth_head(model.model) is None:\n    raise SystemExit('This depth head has no cal_a/cal_b buffers; use a stock yolo26-depth model')\nmodel.calibrate(data='my_depth_dataset.yaml')","typeGuard":"def has_calibratable_head(model) -> bool:\n    from ultralytics.models.yolo.depth.calibrate import _depth_head\n    return _depth_head(model) is not None","tryCatchPattern":null,"preventionTips":["Calibrate only stock depth checkpoints or heads with cal_a/cal_b buffers.","Keep custom heads' calibration logic in your own code."],"tags":["calibration","depth","custom-head","model-structure"],"backgroundTag":null,"analyzedSha":"0449ea011cfd6c9a0d50a0bf1043aca5190cd476","analyzedAt":"2026-08-15T02:34:13.413Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}