| --- |
| language: |
| - en |
| license: cc-by-nc-sa-4.0 |
| library_name: onnxruntime |
| tags: |
| - ner |
| - pos |
| - dependency-parsing |
| - token-classification |
| - sequence-classification |
| - multi-task |
| - onnx |
| - int8 |
| - quantized |
| - distilroberta |
| - experimental |
| - deprecated |
| datasets: |
| - conll2003 |
| - universal_dependencies |
| pipeline_tag: token-classification |
| model-index: |
| - name: kniv-distilroberta-nlp-en |
| results: |
| - task: |
| type: token-classification |
| name: Named Entity Recognition |
| dataset: |
| type: conll2003 |
| name: CoNLL-2003 |
| metrics: |
| - type: f1 |
| value: 0.909 |
| name: NER F1 |
| - task: |
| type: token-classification |
| name: Part-of-Speech Tagging |
| dataset: |
| type: universal_dependencies |
| name: UD English EWT |
| metrics: |
| - type: accuracy |
| value: 0.976 |
| name: POS Accuracy |
| - task: |
| type: token-classification |
| name: Dependency Parsing |
| dataset: |
| type: universal_dependencies |
| name: UD English EWT |
| metrics: |
| - type: accuracy |
| value: 0.880 |
| name: UAS |
| - type: accuracy |
| value: 0.866 |
| name: LAS |
| --- |
| |
| > **β οΈ DEPRECATED β Experimental Model** |
| > |
| > This model is an early experimental release from the kniv cascade research |
| > program and is **no longer maintained**. It predates the current |
| > 5-head cascade architecture (POS, NER, DEP, SRL, CLS) and the |
| > bottom-up layer-selective training methodology that produces our |
| > current production teacher. |
| > |
| > **Use the current production model instead:** |
| > [`dragonscale-ai/kniv-deberta-nlp-base-en-large`](https://huggingface.co/dragonscale-ai/kniv-deberta-nlp-base-en-large) |
| > |
| > The current model offers significantly better quality across all tasks, |
| > includes Semantic Role Labeling and Dialog Act Classification heads, |
| > and has reproducible benchmarks against standard public test sets. |
| > |
| > This repository is preserved for reproducibility and historical reference. |
| > No further updates, bug fixes, or evaluation runs are planned. |
|
|
| --- |
|
|
| # kniv-distilroberta-nlp-en |
|
|
| Multi-task NLP model for English that performs NER, POS tagging, dependency parsing, and sentence classification in a **single forward pass**. Exported as ONNX with INT8 quantization for fast CPU inference. |
|
|
| > **License note:** This model is **CC BY-NC-SA 4.0** (non-commercial) because it was trained on CoNLL-2003 (research use only) and DailyDialog (CC BY-NC-SA). For a commercially licensed version, see the upcoming `kniv-deberta-v3-nlp-en` models trained on the [kniv-corpus-en](https://huggingface.co/datasets/dragonscale-ai/kniv-corpus-en) dataset. |
|
|
| ## Model Details |
|
|
| | Field | Value | |
| |-------|-------| |
| | **Developer** | [dragonscale-ai](https://huggingface.co/dragonscale-ai) | |
| | **Base model** | `distilroberta-base` (82M parameters) | |
| | **Format** | ONNX (FP32 + INT8 quantized) | |
| | **License** | CC BY-NC-SA 4.0 | |
| | **Language** | English | |
| | **Repository** | [rustic-ai/kniv-nlp-models](https://github.com/rustic-ai/kniv-nlp-models) | |
|
|
| ### Intended Use |
|
|
| Embedded NLP pipeline for the [uniko](https://github.com/rustic-ai/uniko) cognitive memory system. Designed for fast, multi-task inference on CPU β a single model call extracts entities, POS tags, dependency parse, and sentence type simultaneously. |
|
|
| **Not intended for:** Production commercial use (due to NC license). Use the kniv-deberta-v3 models instead. |
|
|
| ## Architecture |
|
|
| Shared DistilRoBERTa encoder with four linear classification heads: |
|
|
| ``` |
| Input text |
| β |
| βΌ |
| ββββββββββββββββββββ |
| β DistilRoBERTa β |
| β (6 layers, 768) β |
| ββββ¬βββ¬βββ¬βββ¬βββββββ |
| β β β β |
| βΌ βΌ βΌ βΌ |
| NER POS Dep CLS |
| ``` |
|
|
| | Head | Labels | Training Data | Metric | |
| |------|--------|---------------|--------| |
| | **NER** | 9 (BIO: PER, ORG, LOC, MISC) | CoNLL-2003 | F1 = 90.9% | |
| | **POS** | 17 (UPOS tagset) | UD English EWT v2.14 | Acc = 97.6% | |
| | **Dep** | 1,440 (dep2label composite tags) | UD English EWT v2.14 | UAS = 88.0%, LAS = 86.6% | |
| | **CLS** | 7 (statement, question, command, ...) | Bootstrap labels | F1 = 78.0% | |
|
|
| ### dep2label Encoding |
|
|
| Dependency parsing is reformulated as token classification using [Strzyz et al. (2019)](https://aclanthology.org/N19-1077/). Each token receives a label like `+1@nsubj@VERB` encoding the head direction, dependency relation, and head POS. |
|
|
| ## Evaluation Results |
|
|
| ### NER (CoNLL-2003 Test) |
|
|
| | Entity | Precision | Recall | F1 | |
| |--------|-----------|--------|-----| |
| | PER | 95.6% | 95.9% | **95.7%** | |
| | LOC | 91.4% | 93.5% | **92.4%** | |
| | ORG | 88.7% | 89.4% | **89.0%** | |
| | MISC | 78.4% | 82.8% | **80.5%** | |
| | **Overall** | **90.1%** | **91.6%** | **90.9%** | |
|
|
| ### POS (UD English EWT Test) |
|
|
| **Accuracy: 97.6%** (24,491 / 25,094 tokens correct) |
|
|
| Top confusions: PROPNβNOUN (229), NOUNβADJ (51), ADJβVERB (18) |
|
|
| ### Dependency Parsing (UD English EWT Test) |
|
|
| | Metric | Score | |
| |--------|-------| |
| | **UAS** | **88.0%** | |
| | **LAS** | **86.6%** | |
|
|
| Performance by sentence length: |
| - Short (<10 tokens): 88.8% |
| - Medium (10-20): 89.7% |
| - Long (20-40): 87.2% |
| - Very long (40+): 84.1% |
|
|
| ### Sentence Classification |
|
|
| | Class | Precision | Recall | F1 | |
| |-------|-----------|--------|-----| |
| | statement | 99.9% | 99.9% | 99.9% | |
| | question | 99.4% | 100% | 99.7% | |
| | command | 100% | 91.7% | 95.7% | |
| | filler | 94.3% | 97.1% | 95.7% | |
| | acknowledgment | 100% | 66.7% | 80.0% | |
| | greeting | 60.0% | 100% | 75.0% | |
|
|
| ## Model Files |
|
|
| | File | Size | Description | |
| |------|------|-------------| |
| | `model.onnx` | 316 MB | FP32 ONNX model | |
| | `model-int8.onnx` | **79 MB** | INT8 quantized (recommended) | |
| | `label_maps.json` | 31 KB | NER/POS/Dep/CLS label vocabularies | |
| | `tokenizer.json` | 3.4 MB | DistilRoBERTa tokenizer | |
|
|
| ### FP32 vs INT8 |
|
|
| | | FP32 | INT8 | |
| |---|---|---| |
| | **Size** | 316 MB | **79 MB** (75% smaller) | |
| | **Latency (CPU)** | 74 ms | **35 ms** (2.1x faster) | |
| | **NER prediction match** | β | 98.6% | |
| | **POS prediction match** | β | 98.6% | |
| | **CLS prediction match** | β | 100% | |
|
|
| ## Usage |
|
|
| ### Python (ONNX Runtime) |
|
|
| ```python |
| import json |
| import numpy as np |
| import onnxruntime as ort |
| from transformers import AutoTokenizer |
| |
| # Load model and tokenizer |
| session = ort.InferenceSession("model-int8.onnx") |
| tokenizer = AutoTokenizer.from_pretrained(".") |
| |
| with open("label_maps.json") as f: |
| labels = json.load(f) |
| |
| # Run inference |
| text = "Apple reported $394B revenue in Q4." |
| inputs = tokenizer(text, return_tensors="np", padding="max_length", |
| max_length=128, truncation=True) |
| |
| outputs = session.run(None, { |
| "input_ids": inputs["input_ids"], |
| "attention_mask": inputs["attention_mask"], |
| }) |
| |
| # outputs[0] = ner_logits, [1] = pos_logits, [2] = dep_logits, [3] = cls_logits |
| |
| # Extract NER predictions |
| ner_preds = outputs[0][0].argmax(axis=-1) |
| tokens = tokenizer.convert_ids_to_tokens(inputs["input_ids"][0]) |
| for tok, pred in zip(tokens, ner_preds): |
| if pred > 0: # non-O |
| print(f" {tok} β {labels['ner_labels'][pred]}") |
| |
| # Sentence classification |
| cls_pred = labels["cls_labels"][outputs[3][0].argmax()] |
| print(f" CLS: {cls_pred}") |
| ``` |
|
|
| ### Rust (ONNX Runtime) |
|
|
| ```rust |
| let session = ort::Session::builder()?.with_model("model-int8.onnx")?; |
| |
| let encoding = tokenizer.encode("Apple reported $394B revenue.", true); |
| let outputs = session.run(inputs)?; |
| |
| let ner_logits = &outputs["ner_logits"]; // [1, seq_len, 9] |
| let pos_logits = &outputs["pos_logits"]; // [1, seq_len, 17] |
| let dep_logits = &outputs["dep_logits"]; // [1, seq_len, 1440] |
| let cls_logits = &outputs["cls_logits"]; // [1, 7] |
| ``` |
|
|
| ## Training |
|
|
| ```bash |
| git clone https://github.com/rustic-ai/kniv-nlp-models |
| cd kniv-nlp-models |
| |
| # This model was trained with the original pipeline (before kniv corpus): |
| python models/distilroberta-nlp-en/prepare_data.py |
| python models/distilroberta-nlp-en/train.py |
| python -m shared.export_onnx \ |
| --model-dir outputs/distilroberta-nlp-en/best \ |
| --encoder distilroberta-base \ |
| --output-dir onnx-output/distilroberta-nlp-en |
| ``` |
|
|
| ## Limitations |
|
|
| - **Non-commercial license** β trained on CoNLL-2003 (research only) and DailyDialog (CC BY-NC-SA) |
| - **4 NER types only** β PER, ORG, LOC, MISC (the newer kniv models have 18 types) |
| - **English only** β no multilingual support |
| - **128 token max** β sentences longer than 128 subword tokens are truncated |
| - **CLS labels are bootstrapped** β rule-based heuristics, not gold-standard annotations |
| - **dep2label decoding depends on POS** β POS errors cascade into dependency errors |
|
|
| ## Citation |
|
|
| ```bibtex |
| @misc{kniv-distilroberta-nlp-en, |
| title={kniv-distilroberta-nlp-en: Multi-task NLP Model for English}, |
| author={Dragonscale AI}, |
| year={2026}, |
| publisher={Hugging Face}, |
| url={https://huggingface.co/dragonscale-ai/kniv-distilroberta-nlp-en} |
| } |
| |
| @inproceedings{strzyz-etal-2019-viable, |
| title = "Viable Dependency Parsing as Sequence Labeling", |
| author = "Strzyz, Michalina and Vilares, David and G{\'o}mez-Rodr{\'\i}guez, Carlos", |
| booktitle = "Proceedings of NAACL", |
| year = "2019" |
| } |
| ``` |
|
|
| ## See Also |
|
|
| - **Dataset:** [dragonscale-ai/kniv-corpus-en](https://huggingface.co/datasets/dragonscale-ai/kniv-corpus-en) β 657K sentences, CC BY-SA 4.0 |
| - **Commercial models (upcoming):** |
| - `kniv-deberta-v3-large-nlp-en` β 304M teacher, 18 NER types, 9 CLS labels |
| - `kniv-deberta-v3-nlp-en` β 44M distilled student |
| - **Source code:** [rustic-ai/kniv-nlp-models](https://github.com/rustic-ai/kniv-nlp-models) |
|
|