Skip to content

Commit 0c8b517

Browse files
authored
performance: support padatious (#42)
* performance: support padatious * performance: support padatious * tests
1 parent 065d3a2 commit 0c8b517

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

ocp_pipeline/opm.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
from ovos_utils.ocp import MediaType, PlaybackType, PlaybackMode, PlayerState, OCP_ID, \
2222
MediaEntry, Playlist, MediaState, TrackState, dict2entry, PluginStream
2323
from ovos_workshop.app import OVOSAbstractApplication
24-
from padacioso import IntentContainer
24+
from ovos_utils.xdg_utils import xdg_data_home
25+
from ovos_config.meta import get_xdg_base
2526

2627
from ocp_pipeline.feats import OCPFeaturizer
2728
from ocp_pipeline.legacy import LegacyCommonPlay
@@ -48,6 +49,7 @@ class OCPPipelineMatcher(ConfidenceMatcherPipeline, OVOSAbstractApplication):
4849
"next.intent", "prev.intent", "pause.intent", "play_favorites.intent",
4950
"resume.intent", "like_song.intent"]
5051
intent_matchers = {}
52+
intent_cache = f"{xdg_data_home()}/{get_xdg_base()}/intent_cache"
5153

5254
def __init__(self, bus: Optional[Union[MessageBusClient, FakeBus]] = None,
5355
config: Optional[Dict] = None):
@@ -150,9 +152,22 @@ def register_ocp_api_events(self):
150152
@classmethod
151153
def load_intent_files(cls):
152154
intent_files = cls.load_resource_files()
155+
156+
try:
157+
from ovos_padatious import IntentContainer
158+
is_padatious = True
159+
except ImportError:
160+
from padacioso import IntentContainer
161+
is_padatious = False
162+
LOG.warning("Padatious not available, using padacioso. intent matching will be orders of magnitude slower!")
163+
153164
for lang, intent_data in intent_files.items():
154165
lang = standardize_lang_tag(lang)
155-
cls.intent_matchers[lang] = IntentContainer()
166+
if is_padatious:
167+
cache = f"{cls.intent_cache}/{lang}"
168+
cls.intent_matchers[lang] = IntentContainer(cache)
169+
else:
170+
cls.intent_matchers[lang] = IntentContainer()
156171
for intent_name in cls.intents:
157172
samples = intent_data.get(intent_name)
158173
if samples:
@@ -301,6 +316,10 @@ def handle_player_state_update(self, message: Message):
301316
def match_high(self, utterances: List[str], lang: str, message: Message = None) -> Optional[IntentHandlerMatch]:
302317
""" exact matches only, handles playback control
303318
recommended after high confidence intents pipeline stage """
319+
320+
if not len(self.skill_aliases): # skill_id registered when skills load
321+
return None # dont waste compute cycles, no media skills -> no match
322+
304323
lang = self._get_closest_lang(lang)
305324
if lang is None: # no intents registered for this lang
306325
return None
@@ -310,9 +329,21 @@ def match_high(self, utterances: List[str], lang: str, message: Message = None)
310329
utterance = utterances[0].lower()
311330
match = self.intent_matchers[lang].calc_intent(utterance)
312331

332+
if hasattr(match, "name"): # padatious
333+
match = {
334+
"name": match.name,
335+
"conf": match.conf,
336+
"entities": match.matches
337+
}
338+
313339
if match["name"] is None:
314340
return None
315-
LOG.info(f"OCP exact match: {match}")
341+
342+
if match.get("conf", 1.0) < 0.7:
343+
LOG.debug(f"Ignoring low confidence OCP match: {match}")
344+
return None
345+
346+
LOG.info(f"OCP match: {match}")
316347

317348
player = self.get_player(message)
318349

@@ -1128,6 +1159,12 @@ def match(self, utterances: List[str], lang: str, message: Message = None) -> Op
11281159
return None
11291160

11301161
match = OCPPipelineMatcher.intent_matchers[lang].calc_intent(utterance)
1162+
if hasattr(match, "name"): # padatious
1163+
match = {
1164+
"name": match.name,
1165+
"conf": match.conf,
1166+
"entities": match.matches
1167+
}
11311168

11321169
if match["name"] is None:
11331170
return None

tests/test_ocp.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ def setUp(self):
5050
os.path.dirname(ocp_pipeline.opm.__file__) + "/models/ocp_entities_v0.csv"
5151
]}
5252
self.ocp = OCPPipelineMatcher(config=config)
53+
self.ocp.skill_aliases["test"] = ["Test Skill"] # pretend a skill is loaded or matching is skipped
5354

5455
def test_match_high(self):
5556
result = self.ocp.match_high(["play metallica"], "en-US")
@@ -114,6 +115,7 @@ def setUp(self):
114115
os.path.dirname(ocp_pipeline.opm.__file__) + "/models/ocp_entities_v0.csv"
115116
]}
116117
self.ocp = OCPPipelineMatcher(config=config)
118+
self.ocp.skill_aliases["test"] = ["Test Skill"] # pretend a skill is loaded or matching is skipped
117119

118120
def test_match_high(self):
119121
result = self.ocp.match_high(["play metallica"], "en-US")

0 commit comments

Comments
 (0)