Detection tuning
Out of the box, Fregata runs a bundled YOLOv9-tiny model at 320×320 on the Apple Neural Engine. This is fast (~1–4 ms per frame), private (it’s an ONNX file inside the app bundle, no cloud), and “good enough” for porches, driveways, and most outdoor uses. This page covers everything you’d reach for when “good enough” isn’t.
What’s running, by default
Section titled “What’s running, by default”The defaults that ship with the app:
detectors: coreml: type: coreml inference_backend: ane # "ane" | "gpu" coreml_flags: 0 model: model_type: yolo-generic width: 320 height: 320 input_tensor: nchw input_pixel_format: rgb input_dtype: floatTranslated:
type: coreml— the only detector type that ships in Fregata. No EdgeTPU, TensorRT, OpenVINO, ROCm, RKNN, Hailo. Those don’t apply on macOS. (For the full list of what’s removed, see Fregata vs Frigate.)inference_backend: ane— route inference through ONNX Runtime’s CoreML execution provider, in NeuralNetwork format, preferring the ANE. Fall through to the GPU or CPU only when ops aren’t supported. Switch togputo force MLProgram + Metal.coreml_flags: 0—0lets the runtime pick ANE/GPU/CPU freely;1excludes the ANE.model_type: yolo-generic— generic YOLO postprocessor. Other supported types:yolox,yolonas,dfine,rfdetr,ssd.
ANE vs GPU — which should I use?
Section titled “ANE vs GPU — which should I use?”The honest answer: leave it on ane and don’t think about it
again for the bundled model and the typical Frigate+ models. The
ANE is the faster path on Apple Silicon for INT8 / FP16 YOLO-shaped
networks, and the runtime falls back automatically when an op isn’t
supported.
Switch to inference_backend: gpu when:
- You’re running a model the CoreML compiler can’t lower onto the ANE (you’ll see this on first warmup as a CPU-tier latency).
- You want to A/B test latency or thermals on a specific machine.
- You’re hitting a known ANE bug on a specific macOS build and need to ship a fix today.
On an M1 Pro, ANE inference for YOLOv9-tiny at 320×320 is in the 1–2 ms range; GPU is 4–8 ms; CPU is 40–80 ms. The CPU path is correctness-only — never run a real install on it.
Masks blank out parts of the frame before motion detection runs, which is the right place to ignore tree branches, your neighbour’s front porch, and anywhere a flag waves all day.
Two flavours:
cameras: front_porch: motion: mask: - 0,0,0,400,300,400,300,0 objects: filters: person: mask: - 800,0,1280,0,1280,200,800,200motion.mask— pixels excluded from motion altogether. No motion signal, no detector pass, no event.objects.filters.<class>.mask— pixels where a detection of that class is suppressed even if motion got us there. Use this for “ignore the person on the TV” scenarios.
The web UI has a polygon editor under Settings → Masks & Zones. Draw, save, repeat.

Zones are named polygons. They don’t change whether an object is detected — they change what events that detection creates and what gets sent to MQTT or Home Assistant.
cameras: driveway: zones: driveway_apron: coordinates: 0,720,400,720,500,500,0,500 objects: - car - truck mailbox: coordinates: 1100,400,1280,400,1280,500,1100,500A car event in driveway_apron will fire as a zone-entry event.
A person walking past the mailbox won’t, because mailbox doesn’t
list person.
This is the same configuration shape upstream Frigate uses; their zones documentation covers more advanced shapes.
Per-object thresholds
Section titled “Per-object thresholds”The bundled YOLO model returns a confidence score for every box. A sensible default is to ignore anything under ~0.5, and to be stricter (~0.7) for classes that are easy to confuse with similar objects:
objects: track: - person - car - dog filters: person: threshold: 0.7 min_area: 1500 dog: threshold: 0.65min_area is in pixels; it kills tiny detections — usually
distant people that hover at low confidence.
Bringing your own model
Section titled “Bringing your own model”Fregata supports any ONNX model that ONNX Runtime’s CoreML provider can run. The most common reasons to swap:
- You bought a Frigate+ subscription and want to use your custom-trained model. See below.
- You’ve trained YOLOv9 / YOLOv10 / RT-DETR yourself and have
an
onnxexport. Drop it in. - You want classes the bundled model doesn’t have — e.g. bicycles, packages, license plates, drones.
Place the ONNX file somewhere persistent (the conventional spot is
~/Fregata/config/models/my_model.onnx) and point the config at it:
detectors: coreml: type: coreml inference_backend: ane model_path: /Users/<you>/Fregata/config/models/my_model.onnx model: model_type: yolo-generic # or yolox, yolonas, dfine, rfdetr, ssd width: 640 height: 640 input_tensor: nchw input_pixel_format: rgb input_dtype: float labelmap_path: /Users/<you>/Fregata/config/models/labels.txtThe labelmap_path is a plain text file with one class label per
line, matching the model’s output indices. If you skip it, Fregata
falls back to the COCO label map that ships with the app.
Frigate+
Section titled “Frigate+”Frigate+ models work natively. You’ll see them on your account
dashboard with a plus://... identifier; paste that into
model_path:
detectors: coreml: type: coreml model_path: plus://abc123def456Fregata fetches the model into ~/Fregata/config/model_cache/ on
first launch and validates the architecture. It checks the model’s
declared supportedDetectors field for onnx (CoreML maps to ONNX
under the hood); if your Frigate+ model is older than the
onnx-support cutover, retrain on the dashboard for free.
Verifying a model swap worked
Section titled “Verifying a model swap worked”After a config reload (or Restart Frigate from the tray):
- Watch the Detector row in the tray. The first inference logs
a warmup-tier classification —
ANE,GPU, orCPU. CPU after a model swap usually means an unsupported op. - Open the web UI’s System tab. The “Detector inference time” chart should plateau within a few seconds at the same tier.
- Send an obvious test through (walk past the camera, drop a package). If the bounding box is centred on the right object, you’re done.
If the inference time has jumped from ~2 ms to 50+ ms, you’ve
fallen back to CPU. Either set inference_backend: gpu or
re-export the model with op set ≤ 17 — see
Troubleshooting.