mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-05-06 13:37:43 +03:00
Compare commits
3 Commits
ba4f4304ec
...
26d4f5f0ab
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26d4f5f0ab | ||
|
|
2f9308e0b1 | ||
|
|
886d9c4a55 |
@ -237,8 +237,18 @@ ENV PYTHONWARNINGS="ignore:::numpy.core.getlimits"
|
|||||||
# Set HailoRT to disable logging
|
# Set HailoRT to disable logging
|
||||||
ENV HAILORT_LOGGER_PATH=NONE
|
ENV HAILORT_LOGGER_PATH=NONE
|
||||||
|
|
||||||
# TensorFlow error only
|
# TensorFlow C++ logging suppression (must be set before import)
|
||||||
|
# TF_CPP_MIN_LOG_LEVEL: 0=all, 1=INFO+, 2=WARNING+, 3=ERROR+ (we use 3 for errors only)
|
||||||
ENV TF_CPP_MIN_LOG_LEVEL=3
|
ENV TF_CPP_MIN_LOG_LEVEL=3
|
||||||
|
# Suppress verbose logging from TensorFlow C++ code
|
||||||
|
ENV TF_CPP_MIN_VLOG_LEVEL=3
|
||||||
|
# Disable oneDNN optimization messages ("optimized with oneDNN...")
|
||||||
|
ENV TF_ENABLE_ONEDNN_OPTS=0
|
||||||
|
# Suppress AutoGraph verbosity during conversion
|
||||||
|
ENV AUTOGRAPH_VERBOSITY=0
|
||||||
|
# Google Logging (GLOG) suppression for TensorFlow components
|
||||||
|
ENV GLOG_minloglevel=3
|
||||||
|
ENV GLOG_logtostderr=0
|
||||||
|
|
||||||
ENV PATH="/usr/local/go2rtc/bin:/usr/local/tempio/bin:/usr/local/nginx/sbin:${PATH}"
|
ENV PATH="/usr/local/go2rtc/bin:/usr/local/tempio/bin:/usr/local/nginx/sbin:${PATH}"
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ from frigate.comms.event_metadata_updater import (
|
|||||||
)
|
)
|
||||||
from frigate.config import FrigateConfig
|
from frigate.config import FrigateConfig
|
||||||
from frigate.const import MODEL_CACHE_DIR
|
from frigate.const import MODEL_CACHE_DIR
|
||||||
from frigate.log import redirect_output_to_logger
|
from frigate.log import suppress_stderr_during
|
||||||
from frigate.util.object import calculate_region
|
from frigate.util.object import calculate_region
|
||||||
|
|
||||||
from ..types import DataProcessorMetrics
|
from ..types import DataProcessorMetrics
|
||||||
@ -80,13 +80,14 @@ class BirdRealTimeProcessor(RealTimeProcessorApi):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to download {path}: {e}")
|
logger.error(f"Failed to download {path}: {e}")
|
||||||
|
|
||||||
@redirect_output_to_logger(logger, logging.DEBUG)
|
|
||||||
def __build_detector(self) -> None:
|
def __build_detector(self) -> None:
|
||||||
self.interpreter = Interpreter(
|
# Suppress TFLite delegate creation messages that bypass Python logging
|
||||||
model_path=os.path.join(MODEL_CACHE_DIR, "bird/bird.tflite"),
|
with suppress_stderr_during("tflite_interpreter_init"):
|
||||||
num_threads=2,
|
self.interpreter = Interpreter(
|
||||||
)
|
model_path=os.path.join(MODEL_CACHE_DIR, "bird/bird.tflite"),
|
||||||
self.interpreter.allocate_tensors()
|
num_threads=2,
|
||||||
|
)
|
||||||
|
self.interpreter.allocate_tensors()
|
||||||
self.tensor_input_details = self.interpreter.get_input_details()
|
self.tensor_input_details = self.interpreter.get_input_details()
|
||||||
self.tensor_output_details = self.interpreter.get_output_details()
|
self.tensor_output_details = self.interpreter.get_output_details()
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@ from frigate.config.classification import (
|
|||||||
ObjectClassificationType,
|
ObjectClassificationType,
|
||||||
)
|
)
|
||||||
from frigate.const import CLIPS_DIR, MODEL_CACHE_DIR
|
from frigate.const import CLIPS_DIR, MODEL_CACHE_DIR
|
||||||
from frigate.log import redirect_output_to_logger
|
from frigate.log import suppress_stderr_during
|
||||||
from frigate.types import TrackedObjectUpdateTypesEnum
|
from frigate.types import TrackedObjectUpdateTypesEnum
|
||||||
from frigate.util.builtin import EventsPerSecond, InferenceSpeed, load_labels
|
from frigate.util.builtin import EventsPerSecond, InferenceSpeed, load_labels
|
||||||
from frigate.util.object import box_overlaps, calculate_region
|
from frigate.util.object import box_overlaps, calculate_region
|
||||||
@ -72,7 +72,6 @@ class CustomStateClassificationProcessor(RealTimeProcessorApi):
|
|||||||
self.last_run = datetime.datetime.now().timestamp()
|
self.last_run = datetime.datetime.now().timestamp()
|
||||||
self.__build_detector()
|
self.__build_detector()
|
||||||
|
|
||||||
@redirect_output_to_logger(logger, logging.DEBUG)
|
|
||||||
def __build_detector(self) -> None:
|
def __build_detector(self) -> None:
|
||||||
try:
|
try:
|
||||||
from tflite_runtime.interpreter import Interpreter
|
from tflite_runtime.interpreter import Interpreter
|
||||||
@ -89,11 +88,13 @@ class CustomStateClassificationProcessor(RealTimeProcessorApi):
|
|||||||
self.labelmap = {}
|
self.labelmap = {}
|
||||||
return
|
return
|
||||||
|
|
||||||
self.interpreter = Interpreter(
|
# Suppress TFLite delegate creation messages that bypass Python logging
|
||||||
model_path=model_path,
|
with suppress_stderr_during("tflite_interpreter_init"):
|
||||||
num_threads=2,
|
self.interpreter = Interpreter(
|
||||||
)
|
model_path=model_path,
|
||||||
self.interpreter.allocate_tensors()
|
num_threads=2,
|
||||||
|
)
|
||||||
|
self.interpreter.allocate_tensors()
|
||||||
self.tensor_input_details = self.interpreter.get_input_details()
|
self.tensor_input_details = self.interpreter.get_input_details()
|
||||||
self.tensor_output_details = self.interpreter.get_output_details()
|
self.tensor_output_details = self.interpreter.get_output_details()
|
||||||
self.labelmap = load_labels(labelmap_path, prefill=0)
|
self.labelmap = load_labels(labelmap_path, prefill=0)
|
||||||
@ -377,7 +378,6 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi):
|
|||||||
|
|
||||||
self.__build_detector()
|
self.__build_detector()
|
||||||
|
|
||||||
@redirect_output_to_logger(logger, logging.DEBUG)
|
|
||||||
def __build_detector(self) -> None:
|
def __build_detector(self) -> None:
|
||||||
model_path = os.path.join(self.model_dir, "model.tflite")
|
model_path = os.path.join(self.model_dir, "model.tflite")
|
||||||
labelmap_path = os.path.join(self.model_dir, "labelmap.txt")
|
labelmap_path = os.path.join(self.model_dir, "labelmap.txt")
|
||||||
@ -389,11 +389,13 @@ class CustomObjectClassificationProcessor(RealTimeProcessorApi):
|
|||||||
self.labelmap = {}
|
self.labelmap = {}
|
||||||
return
|
return
|
||||||
|
|
||||||
self.interpreter = Interpreter(
|
# Suppress TFLite delegate creation messages that bypass Python logging
|
||||||
model_path=model_path,
|
with suppress_stderr_during("tflite_interpreter_init"):
|
||||||
num_threads=2,
|
self.interpreter = Interpreter(
|
||||||
)
|
model_path=model_path,
|
||||||
self.interpreter.allocate_tensors()
|
num_threads=2,
|
||||||
|
)
|
||||||
|
self.interpreter.allocate_tensors()
|
||||||
self.tensor_input_details = self.interpreter.get_input_details()
|
self.tensor_input_details = self.interpreter.get_input_details()
|
||||||
self.tensor_output_details = self.interpreter.get_output_details()
|
self.tensor_output_details = self.interpreter.get_output_details()
|
||||||
self.labelmap = load_labels(labelmap_path, prefill=0)
|
self.labelmap = load_labels(labelmap_path, prefill=0)
|
||||||
|
|||||||
@ -5,7 +5,7 @@ from typing_extensions import Literal
|
|||||||
|
|
||||||
from frigate.detectors.detection_api import DetectionApi
|
from frigate.detectors.detection_api import DetectionApi
|
||||||
from frigate.detectors.detector_config import BaseDetectorConfig
|
from frigate.detectors.detector_config import BaseDetectorConfig
|
||||||
from frigate.log import redirect_output_to_logger
|
from frigate.log import suppress_stderr_during
|
||||||
|
|
||||||
from ..detector_utils import tflite_detect_raw, tflite_init
|
from ..detector_utils import tflite_detect_raw, tflite_init
|
||||||
|
|
||||||
@ -28,12 +28,13 @@ class CpuDetectorConfig(BaseDetectorConfig):
|
|||||||
class CpuTfl(DetectionApi):
|
class CpuTfl(DetectionApi):
|
||||||
type_key = DETECTOR_KEY
|
type_key = DETECTOR_KEY
|
||||||
|
|
||||||
@redirect_output_to_logger(logger, logging.DEBUG)
|
|
||||||
def __init__(self, detector_config: CpuDetectorConfig):
|
def __init__(self, detector_config: CpuDetectorConfig):
|
||||||
interpreter = Interpreter(
|
# Suppress TFLite delegate creation messages that bypass Python logging
|
||||||
model_path=detector_config.model.path,
|
with suppress_stderr_during("tflite_interpreter_init"):
|
||||||
num_threads=detector_config.num_threads or 3,
|
interpreter = Interpreter(
|
||||||
)
|
model_path=detector_config.model.path,
|
||||||
|
num_threads=detector_config.num_threads or 3,
|
||||||
|
)
|
||||||
|
|
||||||
tflite_init(self, interpreter)
|
tflite_init(self, interpreter)
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import numpy as np
|
|||||||
from frigate.const import MODEL_CACHE_DIR
|
from frigate.const import MODEL_CACHE_DIR
|
||||||
from frigate.detectors.detection_runners import get_optimized_runner
|
from frigate.detectors.detection_runners import get_optimized_runner
|
||||||
from frigate.embeddings.types import EnrichmentModelTypeEnum
|
from frigate.embeddings.types import EnrichmentModelTypeEnum
|
||||||
from frigate.log import redirect_output_to_logger
|
from frigate.log import suppress_stderr_during
|
||||||
from frigate.util.downloader import ModelDownloader
|
from frigate.util.downloader import ModelDownloader
|
||||||
|
|
||||||
from ...config import FaceRecognitionConfig
|
from ...config import FaceRecognitionConfig
|
||||||
@ -57,17 +57,18 @@ class FaceNetEmbedding(BaseEmbedding):
|
|||||||
self._load_model_and_utils()
|
self._load_model_and_utils()
|
||||||
logger.debug(f"models are already downloaded for {self.model_name}")
|
logger.debug(f"models are already downloaded for {self.model_name}")
|
||||||
|
|
||||||
@redirect_output_to_logger(logger, logging.DEBUG)
|
|
||||||
def _load_model_and_utils(self):
|
def _load_model_and_utils(self):
|
||||||
if self.runner is None:
|
if self.runner is None:
|
||||||
if self.downloader:
|
if self.downloader:
|
||||||
self.downloader.wait_for_download()
|
self.downloader.wait_for_download()
|
||||||
|
|
||||||
self.runner = Interpreter(
|
# Suppress TFLite delegate creation messages that bypass Python logging
|
||||||
model_path=os.path.join(MODEL_CACHE_DIR, "facedet/facenet.tflite"),
|
with suppress_stderr_during("tflite_interpreter_init"):
|
||||||
num_threads=2,
|
self.runner = Interpreter(
|
||||||
)
|
model_path=os.path.join(MODEL_CACHE_DIR, "facedet/facenet.tflite"),
|
||||||
self.runner.allocate_tensors()
|
num_threads=2,
|
||||||
|
)
|
||||||
|
self.runner.allocate_tensors()
|
||||||
self.tensor_input_details = self.runner.get_input_details()
|
self.tensor_input_details = self.runner.get_input_details()
|
||||||
self.tensor_output_details = self.runner.get_output_details()
|
self.tensor_output_details = self.runner.get_output_details()
|
||||||
|
|
||||||
|
|||||||
@ -34,7 +34,7 @@ from frigate.data_processing.real_time.audio_transcription import (
|
|||||||
AudioTranscriptionRealTimeProcessor,
|
AudioTranscriptionRealTimeProcessor,
|
||||||
)
|
)
|
||||||
from frigate.ffmpeg_presets import parse_preset_input
|
from frigate.ffmpeg_presets import parse_preset_input
|
||||||
from frigate.log import LogPipe, redirect_output_to_logger
|
from frigate.log import LogPipe, suppress_stderr_during
|
||||||
from frigate.object_detection.base import load_labels
|
from frigate.object_detection.base import load_labels
|
||||||
from frigate.util.builtin import get_ffmpeg_arg_list
|
from frigate.util.builtin import get_ffmpeg_arg_list
|
||||||
from frigate.util.process import FrigateProcess
|
from frigate.util.process import FrigateProcess
|
||||||
@ -367,17 +367,17 @@ class AudioEventMaintainer(threading.Thread):
|
|||||||
|
|
||||||
|
|
||||||
class AudioTfl:
|
class AudioTfl:
|
||||||
@redirect_output_to_logger(logger, logging.DEBUG)
|
|
||||||
def __init__(self, stop_event: threading.Event, num_threads=2):
|
def __init__(self, stop_event: threading.Event, num_threads=2):
|
||||||
self.stop_event = stop_event
|
self.stop_event = stop_event
|
||||||
self.num_threads = num_threads
|
self.num_threads = num_threads
|
||||||
self.labels = load_labels("/audio-labelmap.txt", prefill=521)
|
self.labels = load_labels("/audio-labelmap.txt", prefill=521)
|
||||||
self.interpreter = Interpreter(
|
# Suppress TFLite delegate creation messages that bypass Python logging
|
||||||
model_path="/cpu_audio_model.tflite",
|
with suppress_stderr_during("tflite_interpreter_init"):
|
||||||
num_threads=self.num_threads,
|
self.interpreter = Interpreter(
|
||||||
)
|
model_path="/cpu_audio_model.tflite",
|
||||||
|
num_threads=self.num_threads,
|
||||||
self.interpreter.allocate_tensors()
|
)
|
||||||
|
self.interpreter.allocate_tensors()
|
||||||
|
|
||||||
self.tensor_input_details = self.interpreter.get_input_details()
|
self.tensor_input_details = self.interpreter.get_input_details()
|
||||||
self.tensor_output_details = self.interpreter.get_output_details()
|
self.tensor_output_details = self.interpreter.get_output_details()
|
||||||
|
|||||||
@ -80,10 +80,15 @@ def apply_log_levels(default: str, log_levels: dict[str, LogLevel]) -> None:
|
|||||||
log_levels = {
|
log_levels = {
|
||||||
"absl": LogLevel.error,
|
"absl": LogLevel.error,
|
||||||
"httpx": LogLevel.error,
|
"httpx": LogLevel.error,
|
||||||
|
"h5py": LogLevel.error,
|
||||||
|
"keras": LogLevel.error,
|
||||||
"matplotlib": LogLevel.error,
|
"matplotlib": LogLevel.error,
|
||||||
"tensorflow": LogLevel.error,
|
"tensorflow": LogLevel.error,
|
||||||
|
"tensorflow.python": LogLevel.error,
|
||||||
"werkzeug": LogLevel.error,
|
"werkzeug": LogLevel.error,
|
||||||
"ws4py": LogLevel.error,
|
"ws4py": LogLevel.error,
|
||||||
|
"PIL": LogLevel.warning,
|
||||||
|
"numba": LogLevel.warning,
|
||||||
**log_levels,
|
**log_levels,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,3 +323,31 @@ def suppress_os_output(func: Callable) -> Callable:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def suppress_stderr_during(operation_name: str) -> Generator[None, None, None]:
|
||||||
|
"""
|
||||||
|
Context manager to suppress stderr output during a specific operation.
|
||||||
|
|
||||||
|
Useful for silencing LLVM debug output, CUDA messages, and other native
|
||||||
|
library logging that cannot be controlled via Python logging or environment
|
||||||
|
variables. Completely redirects file descriptor 2 (stderr) to /dev/null.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
with suppress_stderr_during("model_conversion"):
|
||||||
|
converter = tf.lite.TFLiteConverter.from_keras_model(model)
|
||||||
|
tflite_model = converter.convert()
|
||||||
|
|
||||||
|
Args:
|
||||||
|
operation_name: Name of the operation for debugging purposes
|
||||||
|
"""
|
||||||
|
original_stderr_fd = os.dup(2)
|
||||||
|
devnull = os.open(os.devnull, os.O_WRONLY)
|
||||||
|
try:
|
||||||
|
os.dup2(devnull, 2)
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
os.dup2(original_stderr_fd, 2)
|
||||||
|
os.close(devnull)
|
||||||
|
os.close(original_stderr_fd)
|
||||||
|
|||||||
@ -19,7 +19,7 @@ from frigate.const import (
|
|||||||
PROCESS_PRIORITY_LOW,
|
PROCESS_PRIORITY_LOW,
|
||||||
UPDATE_MODEL_STATE,
|
UPDATE_MODEL_STATE,
|
||||||
)
|
)
|
||||||
from frigate.log import redirect_output_to_logger
|
from frigate.log import redirect_output_to_logger, suppress_stderr_during
|
||||||
from frigate.models import Event, Recordings, ReviewSegment
|
from frigate.models import Event, Recordings, ReviewSegment
|
||||||
from frigate.types import ModelStatusTypesEnum
|
from frigate.types import ModelStatusTypesEnum
|
||||||
from frigate.util.downloader import ModelDownloader
|
from frigate.util.downloader import ModelDownloader
|
||||||
@ -250,15 +250,20 @@ class ClassificationTrainingProcess(FrigateProcess):
|
|||||||
logger.debug(f"Converting {self.model_name} to TFLite...")
|
logger.debug(f"Converting {self.model_name} to TFLite...")
|
||||||
|
|
||||||
# convert model to tflite
|
# convert model to tflite
|
||||||
converter = tf.lite.TFLiteConverter.from_keras_model(model)
|
# Suppress stderr during conversion to avoid LLVM debug output
|
||||||
converter.optimizations = [tf.lite.Optimize.DEFAULT]
|
# (fully_quantize, inference_type, MLIR optimization messages, etc)
|
||||||
converter.representative_dataset = (
|
with suppress_stderr_during("tflite_conversion"):
|
||||||
self.__generate_representative_dataset_factory(dataset_dir)
|
converter = tf.lite.TFLiteConverter.from_keras_model(model)
|
||||||
)
|
converter.optimizations = [tf.lite.Optimize.DEFAULT]
|
||||||
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
|
converter.representative_dataset = (
|
||||||
converter.inference_input_type = tf.uint8
|
self.__generate_representative_dataset_factory(dataset_dir)
|
||||||
converter.inference_output_type = tf.uint8
|
)
|
||||||
tflite_model = converter.convert()
|
converter.target_spec.supported_ops = [
|
||||||
|
tf.lite.OpsSet.TFLITE_BUILTINS_INT8
|
||||||
|
]
|
||||||
|
converter.inference_input_type = tf.uint8
|
||||||
|
converter.inference_output_type = tf.uint8
|
||||||
|
tflite_model = converter.convert()
|
||||||
|
|
||||||
# write model
|
# write model
|
||||||
model_path = os.path.join(model_dir, "model.tflite")
|
model_path = os.path.join(model_dir, "model.tflite")
|
||||||
|
|||||||
@ -65,10 +65,15 @@ class FrigateProcess(BaseProcess):
|
|||||||
logging.basicConfig(handlers=[], force=True)
|
logging.basicConfig(handlers=[], force=True)
|
||||||
logging.getLogger().addHandler(QueueHandler(self.__log_queue))
|
logging.getLogger().addHandler(QueueHandler(self.__log_queue))
|
||||||
|
|
||||||
|
# Always apply base log level suppressions for noisy third-party libraries
|
||||||
|
# even if no specific logConfig is provided
|
||||||
if logConfig:
|
if logConfig:
|
||||||
frigate.log.apply_log_levels(
|
frigate.log.apply_log_levels(
|
||||||
logConfig.default.value.upper(), logConfig.logs
|
logConfig.default.value.upper(), logConfig.logs
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
# Apply default INFO level with standard library suppressions
|
||||||
|
frigate.log.apply_log_levels("INFO", {})
|
||||||
|
|
||||||
self._setup_memray()
|
self._setup_memray()
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user