domi29 commited on
Commit
b2b2763
·
verified ·
1 Parent(s): fa28b8c

Orca-Sonar v5 — 7-class document topic classifier (mmBERT-small) + fp16 ONNX

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ language:
4
+ - de
5
+ - en
6
+ metrics:
7
+ - f1
8
+ - accuracy
9
+ base_model:
10
+ - jhu-clsp/mmBERT-small
11
+ pipeline_tag: text-classification
12
+ tags:
13
+ - document-classification
14
+ - topic-classification
15
+ - security
16
+ - dlp
17
+ - patronus
18
+ - multilingual
19
+ - modernbert
20
+ - text-classification
21
+ - safetensors
22
+ - german
23
+ - english
24
+ - llm-guard
25
+ - protect-ai
26
+
27
+ ---
28
+
29
+ # Model Card for Orca-Sonar
30
+
31
+ **Multilingual Document Topic Classifier for Real-World AI Security & DLP**
32
+
33
+ Orca-Sonar is a Multilingual ModernBERT-based ([mmBERT](https://huggingface.co/blog/mmbert)) classifier that
34
+ assigns a document/text to one of **7 topic classes**. It is part of the Patronus Protect security stack and
35
+ is designed for topic-/risk-routing of incoming texts (e.g. before they reach an LLM, a DLP gate, or a storage tier).
36
+
37
+ It classifies German and English text and is robust to **user-to-AI wrappers** (e.g. *"Summarize this contract: …"*),
38
+ i.e. the *topic* of the content determines the class, not the surface format of the request.
39
+
40
+ ## Intended Uses
41
+
42
+ The model maps an input text to one of:
43
+
44
+ | id | label | description |
45
+ |---|---|---|
46
+ | 0 | `finance` | invoices, balance sheets, quarterly/annual reports, cash-flow, SEC filings, forecasts |
47
+ | 1 | `hr` | CVs, job ads, employment contracts, terminations, HR policies, performance reviews, recruiting |
48
+ | 2 | `internal_and_tech` | ADRs, RFCs, postmortems, specs, READMEs, wikis, architecture & strategy memos, runbooks |
49
+ | 3 | `legal` | contracts, NDAs, ToS/AGB, privacy policies, statutes/judgments, compliance, legal correspondence |
50
+ | 4 | `marketing` | press releases, newsletters, landing-page/sales copy, outbound pitches, case studies |
51
+ | 5 | `other` | conversational / non-business: smalltalk, recipes, travel, hobby, learning, creative |
52
+ | 6 | `source_code` | raw program code & configs (Python/Go/Rust/JS/TS/SQL/Bash/Dockerfile/k8s/Terraform …) |
53
+
54
+ **Disambiguation:** on a tie, the more sensitive class wins —
55
+ `legal > hr > finance > internal_and_tech > source_code > marketing > other`.
56
+
57
+ ## Limitations
58
+
59
+ - Highly accurate on German and English; other languages were not actively tested.
60
+ - The model can produce false positives; for high-stakes routing combine it with a confidence/abstention gate.
61
+ - Robustness against adversarial / out-of-distribution / pure-PII / pathological-length inputs is partial; pair the
62
+ model with a deterministic pre-gate (length + PII) for production DLP use.
63
+
64
+ ## Model Variants
65
+
66
+ - **orca-sonar** – full model (`model.safetensors`, fp32).
67
+ - **orca-sonar-fp16 (ONNX)** – FP16 ONNX export under `onnx/onnx_fp16/` — half the size, argmax-faithful to the full model.
68
+
69
+ # Training Data
70
+
71
+ Trained on our own in-house dataset (German + English, 7 topic classes), purpose-built for this model.
72
+ **The dataset will be published soon.**
73
+
74
+ # Benchmark
75
+
76
+ Held-out test set (**100 % real data**), per-class F1:
77
+
78
+ | Metric | Score |
79
+ |---|---|
80
+ | **Accuracy** | **0.978** |
81
+ | **F1 (macro)** | **0.978** |
82
+ | F1 legal | 0.995 |
83
+ | F1 source_code | 0.985 |
84
+ | F1 marketing | 0.980 |
85
+ | F1 internal_and_tech | 0.977 |
86
+ | F1 hr | 0.971 |
87
+ | F1 finance | 0.970 |
88
+ | F1 other | 0.970 |
89
+
90
+ Out-of-distribution **wrapper-robustness probe** (hand-curated, user-to-AI wrapped real content):
91
+ **29/30 (97 %)** — the topic is recognized through the request wrapper across all business classes.
92
+
93
+ # Usage
94
+
95
+ ```python
96
+ from transformers import pipeline
97
+
98
+ clf = pipeline("text-classification", model="patronus-studio/orca-sonar-document-classifier")
99
+ clf("Fasse mir diesen Dienstleistungsvertrag zusammen: Laufzeit 24 Monate, Gerichtsstand München …")
100
+ # -> [{'label': 'legal', 'score': 0.99}]
101
+ ```
102
+
103
+ ## ONNX
104
+
105
+ An FP16 ONNX version is available under `onnx/onnx_fp16/`:
106
+
107
+ ```python
108
+ import torch
109
+ from optimum.onnxruntime import ORTModelForSequenceClassification
110
+ from transformers import AutoTokenizer
111
+
112
+ model_id = "patronus-studio/orca-sonar-document-classifier"
113
+ tokenizer = AutoTokenizer.from_pretrained(model_id)
114
+ model = ORTModelForSequenceClassification.from_pretrained(model_id, subfolder="onnx/onnx_fp16")
115
+
116
+ inputs = tokenizer("def add(a, b):\n return a + b", return_tensors="pt")
117
+ logits = model(**inputs).logits
118
+ print(model.config.id2label[int(torch.argmax(logits, dim=-1))])
119
+ ```
120
+
121
+ ## Citation
122
+
123
+ ```bibtex
124
+ @misc{orcasonar2026,
125
+ title={Orca-Sonar: Multilingual Document Topic Classification for Real-World AI Security},
126
+ author={Patronus Protect},
127
+ year={2026},
128
+ howpublished={\url{https://huggingface.co/patronus-studio/orca-sonar-document-classifier}}
129
+ }
130
+ ```
config.json ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "ModernBertForSequenceClassification"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "bos_token_id": 2,
8
+ "classifier_activation": "gelu",
9
+ "classifier_bias": false,
10
+ "classifier_dropout": 0.0,
11
+ "classifier_pooling": "mean",
12
+ "cls_token_id": 1,
13
+ "decoder_bias": true,
14
+ "deterministic_flash_attn": false,
15
+ "dtype": "float32",
16
+ "embedding_dropout": 0.0,
17
+ "eos_token_id": 1,
18
+ "global_attn_every_n_layers": 3,
19
+ "gradient_checkpointing": false,
20
+ "hidden_activation": "gelu",
21
+ "hidden_size": 384,
22
+ "id2label": {
23
+ "0": "finance",
24
+ "1": "hr",
25
+ "2": "internal_and_tech",
26
+ "3": "legal",
27
+ "4": "marketing",
28
+ "5": "other",
29
+ "6": "source_code"
30
+ },
31
+ "initializer_cutoff_factor": 2.0,
32
+ "initializer_range": 0.02,
33
+ "intermediate_size": 1152,
34
+ "label2id": {
35
+ "finance": 0,
36
+ "hr": 1,
37
+ "internal_and_tech": 2,
38
+ "legal": 3,
39
+ "marketing": 4,
40
+ "other": 5,
41
+ "source_code": 6
42
+ },
43
+ "layer_norm_eps": 1e-05,
44
+ "layer_types": [
45
+ "full_attention",
46
+ "sliding_attention",
47
+ "sliding_attention",
48
+ "full_attention",
49
+ "sliding_attention",
50
+ "sliding_attention",
51
+ "full_attention",
52
+ "sliding_attention",
53
+ "sliding_attention",
54
+ "full_attention",
55
+ "sliding_attention",
56
+ "sliding_attention",
57
+ "full_attention",
58
+ "sliding_attention",
59
+ "sliding_attention",
60
+ "full_attention",
61
+ "sliding_attention",
62
+ "sliding_attention",
63
+ "full_attention",
64
+ "sliding_attention",
65
+ "sliding_attention",
66
+ "full_attention"
67
+ ],
68
+ "local_attention": 128,
69
+ "mask_token_id": 4,
70
+ "max_position_embeddings": 8192,
71
+ "mlp_bias": false,
72
+ "mlp_dropout": 0.0,
73
+ "model_type": "modernbert",
74
+ "norm_bias": false,
75
+ "norm_eps": 1e-05,
76
+ "num_attention_heads": 6,
77
+ "num_hidden_layers": 22,
78
+ "pad_token_id": 0,
79
+ "position_embedding_type": "sans_pos",
80
+ "problem_type": "single_label_classification",
81
+ "rope_parameters": {
82
+ "full_attention": {
83
+ "rope_theta": 160000,
84
+ "rope_type": "default"
85
+ },
86
+ "sliding_attention": {
87
+ "rope_theta": 160000,
88
+ "rope_type": "default"
89
+ }
90
+ },
91
+ "sep_token_id": 1,
92
+ "sparse_pred_ignore_index": -100,
93
+ "sparse_prediction": false,
94
+ "tie_word_embeddings": true,
95
+ "transformers_version": "5.8.1",
96
+ "use_cache": false,
97
+ "vocab_size": 256000
98
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5c86f42cb39ce056287313b5bec4942bc54d5d2ce1326d2bae702c954d426e52
3
+ size 562591100
onnx/onnx_fp16/model_fp16.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:888e86b79fcaf8de7e9b0c6461f7ced1e345e7d6fc0388b47e97fbb3401dbfb4
3
+ size 281759682
onnx/onnx_fp16/tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4379fe7f4a7af10b1ac15ffc8ae90f446f92082393699e9dd54b8c3b5ec0abad
3
+ size 34363286
onnx/onnx_fp16/tokenizer_config.json ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backend": "tokenizers",
3
+ "bos_token": "<bos>",
4
+ "clean_up_tokenization_spaces": false,
5
+ "cls_token": "<bos>",
6
+ "eos_token": "<eos>",
7
+ "extra_special_tokens": [
8
+ "<start_of_turn>",
9
+ "<end_of_turn>"
10
+ ],
11
+ "is_local": false,
12
+ "local_files_only": false,
13
+ "mask_token": "<mask>",
14
+ "model_input_names": [
15
+ "input_ids",
16
+ "attention_mask"
17
+ ],
18
+ "model_max_length": 8192,
19
+ "pad_token": "<pad>",
20
+ "padding_side": "right",
21
+ "sep_token": "<eos>",
22
+ "spaces_between_special_tokens": false,
23
+ "tokenizer_class": "TokenizersBackend",
24
+ "unk_token": "<unk>"
25
+ }
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4379fe7f4a7af10b1ac15ffc8ae90f446f92082393699e9dd54b8c3b5ec0abad
3
+ size 34363286
tokenizer_config.json ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backend": "tokenizers",
3
+ "bos_token": "<bos>",
4
+ "clean_up_tokenization_spaces": false,
5
+ "cls_token": "<bos>",
6
+ "eos_token": "<eos>",
7
+ "extra_special_tokens": [
8
+ "<start_of_turn>",
9
+ "<end_of_turn>"
10
+ ],
11
+ "is_local": false,
12
+ "local_files_only": false,
13
+ "mask_token": "<mask>",
14
+ "model_input_names": [
15
+ "input_ids",
16
+ "attention_mask"
17
+ ],
18
+ "model_max_length": 8192,
19
+ "pad_token": "<pad>",
20
+ "padding_side": "right",
21
+ "sep_token": "<eos>",
22
+ "spaces_between_special_tokens": false,
23
+ "tokenizer_class": "TokenizersBackend",
24
+ "unk_token": "<unk>"
25
+ }
training_args.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4c7e34b9f8728ad03118313718aa5221f7524aabc42576b3d5c62809693ca052
3
+ size 5329