|
Download README.md from crystas/distilbert-command-data-tagger: direct link, hf CLI and curl.
- Browser
- Download file 5.39 kB
-
https://huggingface.co/crystas/distilbert-command-data-tagger/resolve/main/README.md
- Command line
-
hf download hf://crystas/distilbert-command-data-tagger/README.md
-
curl -L -o README.md https://huggingface.co/crystas/distilbert-command-data-tagger/resolve/main/README.md
5.39 kB
| language: | |
| - en | |
| license: mit | |
| tags: | |
| - distilbert | |
| - onnx | |
| - intent-classification | |
| - token-classification | |
| - ner | |
| - custom-handler | |
| pipeline_tag: text-classification | |
| widget: | |
| - text: bold this sentence | |
| - text: send email to john@example.com | |
| - text: search for previous sentence delete | |
| base_model: | |
| - distilbert/distilbert-base-uncased | |
| # distilbert-command-data-tagger | |
| `distilbert-command-data-tagger` is a lightweight, optimized ONNX model trained for joint **Intent Classification** and **Named Entity Recognition (NER) / Data Tagging** from natural language user commands. | |
| It is designed for lightweight deployment on low-resource runtimes and Hugging Face Inference Endpoints using ONNX Runtime. | |
| --- | |
| ## Model Architecture & Files | |
| - **Base Model**: `distilbert-base-uncased` | |
| - **Model Format**: ONNX (`joint_command_parser.onnx` + `joint_command_parser.onnx.data`) | |
| - **Max Sequence Length**: 64 tokens | |
| - **Output Heads**: | |
| 1. **Intent Logits**: Decodes top-level command intent (with a strict `0.65` confidence threshold fallback to `unknown`). | |
| 2. **NER / Data Tag Logits**: Tagging token sequences (e.g., target text to edit, recipient email address, or search queries). | |
| --- | |
| ## Supported Intents | |
| The model categorizes inputs into one of the following structured categories: | |
| - **Document Editing**: `add_text`, `search_delete`, `prev_sentence_delete`, `bold`, `italic`, `underline` | |
| - **Navigation**: `navigate_email`, `navigate_dm` | |
| - **Email Page Operations**: `email_compose`, `email_send`, `email_reply`, `email_forward`, `email_delete`, `email_search` | |
| - **Direct Message (DM) Operations**: `dm_send`, `dm_reply`, `dm_delete`, `dm_search` | |
| - **Fallback**: `unknown` | |
| --- | |
| ## Inference with Custom Endpoint Handler (`handler.py`) | |
| Below is the standard Hugging Face `EndpointHandler` used to load and run inference on the ONNX graph: | |
| ```python | |
| import os | |
| import numpy as np | |
| import onnxruntime as ort | |
| from transformers import AutoTokenizer | |
| class EndpointHandler: | |
| def __init__(self, path=""): | |
| # 1. Resolve paths for BOTH structural graph and matrix weights | |
| model_path = os.path.join(path, "joint_command_parser.onnx") | |
| # Initialize the ONNX Runtime execution engine thread pool | |
| self.session = ort.InferenceSession(model_path, providers=["CPUExecutionProvider"]) | |
| # 2. Match the exact tokenizer backbone used during training | |
| self.tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased") | |
| # 3. Structural target layouts | |
| self.intents = [ | |
| # document editing | |
| "add_text", | |
| "search_delete", | |
| "prev_sentence_delete", | |
| "bold", | |
| "italic", | |
| "underline", | |
| # navigation | |
| "navigate_email", | |
| "navigate_dm", | |
| # email page | |
| "email_compose", | |
| "email_send", | |
| "email_reply", | |
| "email_forward", | |
| "email_delete", | |
| "email_search", | |
| # dm page | |
| "dm_send", | |
| "dm_reply", | |
| "dm_delete", | |
| "dm_search", | |
| # fallback | |
| "unknown", | |
| ] | |
| self.max_len = 64 | |
| def __call__(self, data): | |
| # Extract input text payload sent via HTTP POST Request | |
| inputs_payload = data.get("inputs", "") | |
| if not inputs_payload: | |
| return {"error": "Missing 'inputs' string parameter inside payload."} | |
| # Tokenize incoming sequence matching matrix bounds | |
| tokenized = self.tokenizer( | |
| inputs_payload, | |
| max_length=self.max_len, | |
| padding="max_length", | |
| truncation=True, | |
| return_tensors="np" | |
| ) | |
| onnx_feeds = { | |
| "input_ids": tokenized["input_ids"].astype(np.int64), | |
| "attention_mask": tokenized["attention_mask"].astype(np.int64) | |
| } | |
| # Run execution graph matrix calculations | |
| intent_logits, ner_logits = self.session.run(None, onnx_feeds) | |
| # Decode Intent array using Softmax calculation | |
| logits_exp = np.exp(intent_logits[0]) | |
| probs = logits_exp / np.sum(logits_exp) | |
| intent_idx = np.argmax(probs) | |
| # Apply strict fallback thresholds | |
| confidence = float(probs[intent_idx]) | |
| final_intent = self.intents[intent_idx] if confidence >= 0.65 else "unknown" | |
| # Process and decode non-zero NER spans | |
| ner_tags = np.argmax(ner_logits[0], axis=-1) | |
| tokens = self.tokenizer.convert_ids_to_tokens(tokenized["input_ids"][0]) | |
| extracted_tokens = [] | |
| for token, tag in zip(tokens, ner_tags): | |
| if token in [self.tokenizer.cls_token, self.tokenizer.sep_token, self.tokenizer.pad_token]: | |
| continue | |
| if tag > 0: # Valid B-DATA or I-DATA sequences | |
| cleaned = token.replace("##", "") | |
| if token.startswith("##") and extracted_tokens: | |
| extracted_tokens[-1] += cleaned | |
| else: | |
| extracted_tokens.append(cleaned) | |
| extracted_data = " ".join(extracted_tokens).strip() | |
| return { | |
| "intent": final_intent, | |
| "confidence": confidence, | |
| "extracted_data": extracted_data | |
| } | |