OVOS Hierarchical KNN Intent Classifier — Granite 97m Multilingual R2

A multilingual intent-classification index for OpenVoiceOS (OVOS) built on top of IBM Granite Embedding 97M Multilingual R2 and a two-stage hierarchical k-NN classifier with Wu-Lin pairwise probability estimation.

What's in this repo

File Description
onnx/model_quint8_avx2.onnx Quantised Granite 97m encoder (AVX2, ~94 MB) — recommended for inference
onnx/model.onnx Full-precision Granite 97m encoder (~372 MB)
tokenizer.json / tokenizer_config.json / special_tokens_map.json Tokenizer files (PreTrainedTokenizerFast)
index.faiss FAISS IVF-PQ index (nlist=1024, pq_m=16, nprobe=32)
meta.pkl Index hyper-parameters and label metadata
label_ids.npy Per-vector label assignments
class_names.npy Sorted array of domain:intent label strings
class_to_train_ids.pkl Mapping from class index → training vector IDs

Index details

  • 201 intents across 39 OVOS skill domains
  • Embedding model: Granite Embedding 97M Multilingual R2 (dim=384, CLS pooling)
  • FAISS index type: IVF1024,PQ16 (inner-product / cosine similarity)
  • Training langs: en, pt, es, fr, it, de, nl, ca, gl, da, eu
  • Hyper-parameters: k=7, n=2 (top-2 domains → intent search), margin=0.1, tau=0.5
Covered skill domains (39)
common_query
ocp
stop
ovos-skill-alerts.openvoiceos
ovos-skill-application-launcher.openvoiceos
ovos-skill-audio-recording.openvoiceos
ovos-skill-boot-finished.openvoiceos
ovos-skill-camera.openvoiceos
ovos-skill-color-picker.krisgesling
ovos-skill-color-picker.krisgesling.openvoiceos
ovos-skill-confucius-quotes.openvoiceos
ovos-skill-count.openvoiceos
ovos-skill-date-time.openvoiceos
ovos-skill-days-in-history.openvoiceos
ovos-skill-ddg.openvoiceos
ovos-skill-diagnostics.openvoiceos
ovos-skill-dictation.openvoiceos
ovos-skill-fuster-quotes.openvoiceos
ovos-skill-hello-world.openvoiceos
ovos-skill-icanhazdadjokes.openvoiceos
ovos-skill-ip.openvoiceos
ovos-skill-iss-location.openvoiceos
ovos-skill-laugh.openvoiceos
ovos-skill-moviemaster.openvoiceos
ovos-skill-naptime.openvoiceos
ovos-skill-news.openvoiceos
ovos-skill-parrot.openvoiceos
ovos-skill-personal.OpenVoiceOS.openvoiceos
ovos-skill-personal.openvoiceos
ovos-skill-randomness.openvoiceos
ovos-skill-screenshot.openvoiceos
ovos-skill-speedtest.openvoiceos
ovos-skill-volume.openvoiceos
ovos-skill-wallpapers.openvoiceos
ovos-skill-weather.openvoiceos
ovos-skill-wikihow.openvoiceos
ovos-skill-wikipedia.openvoiceos
ovos-skill-wolfie.openvoiceos
ovos-skill-wordnet.openvoiceos

Supported languages

The index was trained with utterances in 11 languages. The base Granite model supports many more but only these are covered by the training data:

Code Language
en English
pt Portuguese
es Spanish
fr French
it Italian
de German
nl Dutch
ca Catalan
gl Galician
da Danish
eu Basque

How it works

Classification is a two-stage k-NN search:

  1. L1 — domain search: the query embedding is compared against all training vectors; Wu-Lin pairwise probabilities are computed per skill domain and the top-n domains are selected.
  2. L2 — intent search: a second search is scoped to training vectors that belong only to those top-n domains; Wu-Lin probabilities are computed per intent label.
  3. The L1 and L2 probabilities are multiplied and re-normalised to give a final {label: probability} dict.

At runtime the search can be further restricted to the subset of domains whose skills are actually loaded (via set_active_domains()), which is what the OVOS plugin does automatically.

Usage

Install the OVOS plugin

pip install ovos-hierarchical-knn-pipeline

Load the index

from ovos_hierarchical_knn_pipeline.classifier import HierarchicalPairKNNClassifier

clf = HierarchicalPairKNNClassifier.from_pretrained()

utterances = [
    "what's the weather like tomorrow?",
    "play some jazz music",
    "set an alarm for 7am",
    "qual é a temperatura agora?",   # pt
    "qué hora es?",                  # es
]
predictions = clf.predict(utterances)
for utt, pred in zip(utterances, predictions):
    print(f"{pred:<55}  {utt}")

Get calibrated probabilities

probs_list = clf.predict_proba(utterances)
for utt, probs in zip(utterances, probs_list):
    top = sorted(probs.items(), key=lambda x: x[1], reverse=True)[:3]
    print(f"\n{utt}")
    for label, p in top:
        print(f"  {p:.3f}  {label}")

Restrict search to active skill domains

set_active_domains() pre-computes a FAISS bitmap so only vectors from the specified domains are searched. Call it once after loading the index:

active_skills = [
    "ovos-skill-weather.openvoiceos",
    "ovos-skill-date-time.openvoiceos",
    "common_query",
    "ocp",
    "stop",
]
clf.set_active_domains(active_skills)

probs = clf.predict_proba(["what time is it?"])[0]

OVOS plugin configuration

The plugin downloads the index automatically on first run. Simply add the pipeline to your OVOS mycroft.conf:

{
  "intents": {
    "pipeline": [
      "ovos-hierarchical-knn-pipeline-high",
      "adapt-high",
      "padatious-high",
      "ovos-hierarchical-knn-pipeline-medium",
      "adapt-medium",
      "padatious-medium",
      "ovos-hierarchical-knn-pipeline-low",
      "adapt-low",
      "padatious-low",
      "fallback-low"
    ],
    "ovos_hierarchical_knn_pipeline": {
      "conf_high": 0.70,
      "conf_medium": 0.50,
      "conf_low": 0.15
    }
  }
}

To use a local copy (faster startup, no internet required on boot), set index_dir to a previously downloaded snapshot:

{
  "intents": {
    "ovos_hierarchical_knn_pipeline": {
      "index_dir": "/path/to/local/snapshot"
    }
  }
}

Hardware requirements

Component Requirement
RAM ~320 MB (index + quantised encoder)
CPU x86-64 with AVX2 (model_quint8_avx2.onnx)
Storage ~345 MB total

The quantised ONNX model (model_quint8_avx2.onnx) is used for inference. The full-precision model.onnx is only required when rebuilding the index from scratch (see train/README.md).

License

Apache 2.0 — see LICENSE.

The base embedding model (IBM Granite Embedding 97M Multilingual R2) is also released under Apache 2.0.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support