From 69f963244e53ab82573f2895ee21c520078fe4c4 Mon Sep 17 00:00:00 2001 From: JarbasAI <33701864+JarbasAl@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:06:37 +0000 Subject: [PATCH] performance: paralelize inference (#32) * performance: paralelize inference * Update intent_manager.py --- ovos_padatious/intent_manager.py | 52 +++++++++++++++++++++++++++----- ovos_padatious/simple_intent.py | 2 +- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/ovos_padatious/intent_manager.py b/ovos_padatious/intent_manager.py index fa15588..ddfcb3e 100644 --- a/ovos_padatious/intent_manager.py +++ b/ovos_padatious/intent_manager.py @@ -11,22 +11,58 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - +import time +from concurrent.futures import ThreadPoolExecutor +from typing import List from ovos_padatious.intent import Intent from ovos_padatious.match_data import MatchData from ovos_padatious.training_manager import TrainingManager from ovos_padatious.util import tokenize +from ovos_utils.log import LOG class IntentManager(TrainingManager): - def __init__(self, cache): - super(IntentManager, self).__init__(Intent, cache) + """ + Manages intents and performs matching using the OVOS Padatious framework. + + Args: + cache (str): Path to the cache directory for storing trained models. + """ + def __init__(self, cache: str, debug: bool = False): + super().__init__(Intent, cache) + self.debug = debug + + def calc_intents(self, query: str, entity_manager) -> List[MatchData]: + """ + Calculate matches for the given query against all registered intents. + + Args: + query (str): The input query to match. + entity_manager: The entity manager for resolving entities in the query. - def calc_intents(self, query, entity_manager): + Returns: + List[MatchData]: A list of matches sorted by confidence. + """ sent = tokenize(query) matches = [] - for i in self.objects: - match = i.match(sent, entity_manager) - match.detokenize() - matches.append(match) + + def match_intent(intent): + start_time = time.monotonic() + try: + match = intent.match(sent, entity_manager) + match.detokenize() + if self.debug: + LOG.debug(f"Inference for intent '{intent.name}' took {time.monotonic() - start_time} seconds") + return match + except Exception as e: + LOG.error(f"Error processing intent '{intent.name}': {e}") + return None + + # Parallelize matching + with ThreadPoolExecutor() as executor: + matches = list(executor.map(match_intent, self.objects)) + + # Filter out None results from failed matches + matches = [match for match in matches if match] + return matches diff --git a/ovos_padatious/simple_intent.py b/ovos_padatious/simple_intent.py index 1cd97bc..d03117d 100644 --- a/ovos_padatious/simple_intent.py +++ b/ovos_padatious/simple_intent.py @@ -118,7 +118,7 @@ def calc_weight(w): return pow(len(w), 3.0) train_data = fann.training_data() train_data.set_train_data(inputs, outputs) - LOG.debug(f"Training {self.name} with samples: {n_pos} positive + {n_neg} negative") + LOG.debug(f"Training {self.name} with {len(self.ids)} inputs and samples: {n_pos} positive + {n_neg} negative") for _ in range(10): self.configure_net() self.net.train_on_data(train_data, 1000, 0, 0)