From 5eef8aa2fe9894bec81357c00b511cdf0588c14f Mon Sep 17 00:00:00 2001 From: Daniel McKnight <34697904+NeonDaniel@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:13:00 -0800 Subject: [PATCH] Add timing metrics (#183) # Description Override AudioTransformersService to add timing context and metrics reporting Override listener handlers to add timing context and metrics reporting Adds save_audio timing context and reporting Adds save_ww reporting # Issues # Other Notes --------- Co-authored-by: Daniel McKnight --- neon_speech/__init__.py | 3 +++ neon_speech/service.py | 33 ++++++++++++++++++++++++ neon_speech/transformers.py | 47 +++++++++++++++++++++++++++++++++++ requirements/requirements.txt | 2 +- 4 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 neon_speech/transformers.py diff --git a/neon_speech/__init__.py b/neon_speech/__init__.py index 718d1b0..4af0cae 100644 --- a/neon_speech/__init__.py +++ b/neon_speech/__init__.py @@ -25,3 +25,6 @@ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Import to ensure patched class is applied +from neon_speech.transformers import NeonAudioTransformerService diff --git a/neon_speech/service.py b/neon_speech/service.py index e6feb36..1e9f014 100644 --- a/neon_speech/service.py +++ b/neon_speech/service.py @@ -112,6 +112,8 @@ def __init__(self, ready_hook=on_ready, error_hook=on_error, watchdog=watchdog) self.daemon = daemonic self.config.bus = self.bus + self._stt_stopwatch = Stopwatch("get_stt", allow_reporting=True, + bus=self.bus) from neon_utils.signal_utils import init_signal_handlers, \ init_signal_bus init_signal_bus(self.bus) @@ -133,6 +135,37 @@ def __init__(self, ready_hook=on_ready, error_hook=on_error, LOG.info("Skipping api_stt init") self.api_stt = None + def _record_begin(self): + self._stt_stopwatch.start() + OVOSDinkumVoiceService._record_begin(self) + + def _stt_text(self, text: str, stt_context: dict): + self._stt_stopwatch.stop() + stt_context.setdefault("timing", dict()) + stt_context["timing"]["get_stt"] = self._stt_stopwatch.time + + # This is where the first Message of the interaction is created + OVOSDinkumVoiceService._stt_text(self, text, stt_context) + self._stt_stopwatch.report() + + def _save_stt(self, audio_bytes, stt_meta, save_path=None): + stopwatch = Stopwatch("save_audio", True, self.bus) + with stopwatch: + path = OVOSDinkumVoiceService._save_stt(self, audio_bytes, stt_meta, + save_path) + stt_meta.setdefault('timing', dict()) + stt_meta['timing']['save_audio'] = stopwatch.time + return path + + def _save_ww(self, audio_bytes, ww_meta, save_path=None): + stopwatch = Stopwatch("save_ww", True, self.bus) + with stopwatch: + path = OVOSDinkumVoiceService._save_ww(self, audio_bytes, ww_meta, + save_path) + ww_meta.setdefault('timing', dict()) + ww_meta['timing']['save_ww'] = stopwatch.time + return path + def _validate_message_context(self, message: Message, native_sources=None): if message.context.get('destination') and \ "audio" not in message.context['destination']: diff --git a/neon_speech/transformers.py b/neon_speech/transformers.py new file mode 100644 index 0000000..dde3179 --- /dev/null +++ b/neon_speech/transformers.py @@ -0,0 +1,47 @@ +# NEON AI (TM) SOFTWARE, Software Development Kit & Application Framework +# All trademark and other rights reserved by their respective owners +# Copyright 2008-2022 Neongecko.com Inc. +# Contributors: Daniel McKnight, Guy Daniels, Elon Gasper, Richard Leeds, +# Regina Bloomstine, Casimiro Ferreira, Andrii Pernatii, Kirill Hrymailo +# BSD-3 License +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import ovos_dinkum_listener.transformers +from neon_utils.metrics_utils import Stopwatch +from ovos_dinkum_listener.transformers import AudioTransformersService + + +class NeonAudioTransformerService(AudioTransformersService): + """ + Overrides the default AudioTransformersService to add timing metrics + """ + + def transform(self, chunk: bytes) -> (bytes, dict): + stopwatch = Stopwatch("transform_audio", True, self.bus) + with stopwatch: + chunk, context = AudioTransformersService.transform(self, chunk) + context.setdefault("timing", dict()) + context['timing']['transform_audio'] = stopwatch.time + return chunk, context + + +ovos_dinkum_listener.transformers.AudioTransformersService = NeonAudioTransformerService diff --git a/requirements/requirements.txt b/requirements/requirements.txt index c9f6b97..1a2a78e 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -4,7 +4,7 @@ ovos-utils~=0.0.30 ovos-plugin-manager~=0.0.23 click~=8.0 click-default-group~=1.2 -neon-utils[network,audio]~=1.6 +neon-utils[network,audio]~=1.6,>=1.7.1a4 ovos-config~=0.0.7 ovos-vad-plugin-webrtcvad~=0.0.1