Simplify model config (#15881)

* Add migration to migrate to model_path

* Simplify model config

* Cleanup docs

* Set config version

* Formatting

* Fix tests
This commit is contained in:
Nicolas Mowen 2025-01-07 20:59:37 -07:00 committed by GitHub
parent 4fc9106c17
commit d57a61b50f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 50 additions and 34 deletions

View File

@ -203,14 +203,13 @@ detectors:
ov: ov:
type: openvino type: openvino
device: AUTO device: AUTO
model:
path: /openvino-model/ssdlite_mobilenet_v2.xml
model: model:
width: 300 width: 300
height: 300 height: 300
input_tensor: nhwc input_tensor: nhwc
input_pixel_format: bgr input_pixel_format: bgr
path: /openvino-model/ssdlite_mobilenet_v2.xml
labelmap_path: /openvino-model/coco_91cl_bkgr.txt labelmap_path: /openvino-model/coco_91cl_bkgr.txt
record: record:

View File

@ -144,7 +144,7 @@ detectors:
#### SSDLite MobileNet v2 #### SSDLite MobileNet v2
An OpenVINO model is provided in the container at `/openvino-model/ssdlite_mobilenet_v2.xml` and is used by this detector type by default. The model comes from Intel's Open Model Zoo [SSDLite MobileNet V2](https://github.com/openvinotoolkit/open_model_zoo/tree/master/models/public/ssdlite_mobilenet_v2) and is converted to an FP16 precision IR model. An OpenVINO model is provided in the container at `/openvino-model/ssdlite_mobilenet_v2.xml` and is used by this detector type by default. The model comes from Intel's Open Model Zoo [SSDLite MobileNet V2](https://github.com/openvinotoolkit/open_model_zoo/tree/master/models/public/ssdlite_mobilenet_v2) and is converted to an FP16 precision IR model.
Use the model configuration shown below when using the OpenVINO detector with the default OpenVINO model: Use the model configuration shown below when using the OpenVINO detector with the default OpenVINO model:
@ -506,11 +506,12 @@ detectors:
cpu1: cpu1:
type: cpu type: cpu
num_threads: 3 num_threads: 3
model:
path: "/custom_model.tflite"
cpu2: cpu2:
type: cpu type: cpu
num_threads: 3 num_threads: 3
model:
path: "/custom_model.tflite"
``` ```
When using CPU detectors, you can add one CPU detector per camera. Adding more detectors than the number of cameras should not improve performance. When using CPU detectors, you can add one CPU detector per camera. Adding more detectors than the number of cameras should not improve performance.
@ -637,8 +638,6 @@ detectors:
hailo8l: hailo8l:
type: hailo8l type: hailo8l
device: PCIe device: PCIe
model:
path: /config/model_cache/h8l_cache/ssd_mobilenet_v1.hef
model: model:
width: 300 width: 300
@ -646,4 +645,5 @@ model:
input_tensor: nhwc input_tensor: nhwc
input_pixel_format: bgr input_pixel_format: bgr
model_type: ssd model_type: ssd
path: /config/model_cache/h8l_cache/ssd_mobilenet_v1.hef
``` ```

View File

@ -52,7 +52,7 @@ detectors:
# Required: name of the detector # Required: name of the detector
detector_name: detector_name:
# Required: type of the detector # Required: type of the detector
# Frigate provided types include 'cpu', 'edgetpu', 'openvino' and 'tensorrt' (default: shown below) # Frigate provides many types, see https://docs.frigate.video/configuration/object_detectors for more details (default: shown below)
# Additional detector types can also be plugged in. # Additional detector types can also be plugged in.
# Detectors may require additional configuration. # Detectors may require additional configuration.
# Refer to the Detectors configuration page for more information. # Refer to the Detectors configuration page for more information.

View File

@ -594,35 +594,27 @@ class FrigateConfig(FrigateBaseModel):
if isinstance(detector, dict) if isinstance(detector, dict)
else detector.model_dump(warnings="none") else detector.model_dump(warnings="none")
) )
detector_config: DetectorConfig = adapter.validate_python(model_dict) detector_config: BaseDetectorConfig = adapter.validate_python(model_dict)
if detector_config.model is None:
detector_config.model = self.model.model_copy()
else:
path = detector_config.model.path
detector_config.model = self.model.model_copy()
detector_config.model.path = path
if "path" not in model_dict or len(model_dict.keys()) > 1: # users should not set model themselves
logger.warning( if detector_config.model:
"Customizing more than a detector model path is unsupported." detector_config.model = None
)
merged_model = deep_merge( model_config = self.model.model_dump(exclude_unset=True, warnings="none")
detector_config.model.model_dump(exclude_unset=True, warnings="none"),
self.model.model_dump(exclude_unset=True, warnings="none"),
)
if "path" not in merged_model: if detector_config.model_path:
model_config["path"] = detector_config.model_path
if "path" not in model_config:
if detector_config.type == "cpu": if detector_config.type == "cpu":
merged_model["path"] = "/cpu_model.tflite" model_config["path"] = "/cpu_model.tflite"
elif detector_config.type == "edgetpu": elif detector_config.type == "edgetpu":
merged_model["path"] = "/edgetpu_model.tflite" model_config["path"] = "/edgetpu_model.tflite"
detector_config.model = ModelConfig.model_validate(merged_model) model = ModelConfig.model_validate(model_config)
detector_config.model.check_and_load_plus_model( model.check_and_load_plus_model(self.plus_api, detector_config.type)
self.plus_api, detector_config.type model.compute_model_hash()
) detector_config.model = model
detector_config.model.compute_model_hash()
self.detectors[key] = detector_config self.detectors[key] = detector_config
return self return self

View File

@ -194,6 +194,9 @@ class BaseDetectorConfig(BaseModel):
model: Optional[ModelConfig] = Field( model: Optional[ModelConfig] = Field(
default=None, title="Detector specific model configuration." default=None, title="Detector specific model configuration."
) )
model_path: Optional[str] = Field(
default=None, title="Detector specific model path."
)
model_config = ConfigDict( model_config = ConfigDict(
extra="allow", arbitrary_types_allowed=True, protected_namespaces=() extra="allow", arbitrary_types_allowed=True, protected_namespaces=()
) )

View File

@ -75,11 +75,11 @@ class TestConfig(unittest.TestCase):
"detectors": { "detectors": {
"cpu": { "cpu": {
"type": "cpu", "type": "cpu",
"model": {"path": "/cpu_model.tflite"}, "model_path": "/cpu_model.tflite",
}, },
"edgetpu": { "edgetpu": {
"type": "edgetpu", "type": "edgetpu",
"model": {"path": "/edgetpu_model.tflite"}, "model_path": "/edgetpu_model.tflite",
}, },
"openvino": { "openvino": {
"type": "openvino", "type": "openvino",

View File

@ -13,7 +13,7 @@ from frigate.util.services import get_video_properties
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
CURRENT_CONFIG_VERSION = "0.15-0" CURRENT_CONFIG_VERSION = "0.15-1"
DEFAULT_CONFIG_FILE = "/config/config.yml" DEFAULT_CONFIG_FILE = "/config/config.yml"
@ -77,6 +77,13 @@ def migrate_frigate_config(config_file: str):
yaml.dump(new_config, f) yaml.dump(new_config, f)
previous_version = "0.15-0" previous_version = "0.15-0"
if previous_version < "0.15-1":
logger.info(f"Migrating frigate config from {previous_version} to 0.15-1...")
new_config = migrate_015_1(config)
with open(config_file, "w") as f:
yaml.dump(new_config, f)
previous_version = "0.15-1"
logger.info("Finished frigate config migration...") logger.info("Finished frigate config migration...")
@ -267,6 +274,21 @@ def migrate_015_0(config: dict[str, dict[str, any]]) -> dict[str, dict[str, any]
return new_config return new_config
def migrate_015_1(config: dict[str, dict[str, any]]) -> dict[str, dict[str, any]]:
"""Handle migrating frigate config to 0.15-1"""
new_config = config.copy()
for detector, detector_config in config.get("detectors", {}).items():
path = detector_config.get("model", {}).get("path")
if path:
new_config["detectors"][detector]["model_path"] = path
del new_config["detectors"][detector]["model"]
new_config["version"] = "0.15-1"
return new_config
def get_relative_coordinates( def get_relative_coordinates(
mask: Optional[Union[str, list]], frame_shape: tuple[int, int] mask: Optional[Union[str, list]], frame_shape: tuple[int, int]
) -> Union[str, list]: ) -> Union[str, list]: