oneryalcin commited on
Commit
fb65c5c
·
verified ·
1 Parent(s): 79c2882

Upload ONNX FP32 + INT8 quantized sparse encoder for financial documents

Browse files
README.md ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ language:
3
+ - en
4
+ license: apache-2.0
5
+ tags:
6
+ - sparse-encoder
7
+ - onnx
8
+ - quantized
9
+ - int8
10
+ - splade
11
+ - financial
12
+ - inference-optimized
13
+ base_model: oneryalcin/fin-sparse-encoder-doc-v1
14
+ pipeline_tag: feature-extraction
15
+ library_name: onnxruntime
16
+ ---
17
+
18
+ # fin-sparse-encoder-doc-v1-onnx
19
+
20
+ ONNX + INT8 quantized version of [oneryalcin/fin-sparse-encoder-doc-v1](https://huggingface.co/oneryalcin/fin-sparse-encoder-doc-v1) for CPU-efficient document encoding.
21
+
22
+ This is the **document encoder path only** — it produces sparse SPLADE vectors for indexing financial documents (SEC filings, earnings call transcripts). Query encoding uses a separate IDF lookup table (sub-ms, no neural model needed).
23
+
24
+ ## Model Variants
25
+
26
+ | File | Format | Size | Use Case |
27
+ |---|---|---|---|
28
+ | `model.onnx` | FP32 | 647.9 MB | Maximum accuracy, GPU or high-memory CPU |
29
+ | `model_quantized.onnx` | INT8 | 166.7 MB | **Recommended for CPU deployment** |
30
+
31
+ ## Performance
32
+
33
+ ### Domain Evaluation (Financial Documents)
34
+
35
+ The parent model ([fin-sparse-encoder-doc-v1](https://huggingface.co/oneryalcin/fin-sparse-encoder-doc-v1)) was evaluated on 2,028 held-out financial test examples:
36
+
37
+ | Metric | Base Model | Fine-tuned | Delta |
38
+ |:---|:---|:---|:---|
39
+ | **acc@1** | 39.9% | **55.2%** | +15.2% |
40
+ | **acc@3** | 69.2% | **84.0%** | +14.8% |
41
+ | **ndcg@10** | 0.681 | **0.781** | +10.0% |
42
+ | median_rank | 2.0 | **1.0** | -1.0 |
43
+
44
+ ### Inference Latency (seq_len=512, 1 thread)
45
+
46
+ Benchmarked on Apple M-series CPU. Server CPUs with AVX512-VNNI will see larger INT8 speedups (~2-3x).
47
+
48
+ | Backend | p50 (ms) | p95 (ms) | Model Size |
49
+ |---|---|---|---|
50
+ | PyTorch FP32 | 186.3 | 192.8 | ~620 MB |
51
+ | ONNX FP32 | 211.7 | 218.9 | 647.9 MB |
52
+ | **ONNX INT8** | **164.4** | **166.9** | **166.7 MB** |
53
+
54
+ ## Usage
55
+
56
+ ```python
57
+ import numpy as np
58
+ import onnxruntime as ort
59
+ from transformers import AutoTokenizer
60
+
61
+ # Load
62
+ tokenizer = AutoTokenizer.from_pretrained("oneryalcin/fin-sparse-encoder-doc-v1-onnx")
63
+ sess = ort.InferenceSession("model_quantized.onnx", providers=["CPUExecutionProvider"])
64
+
65
+ # Encode a document
66
+ text = "Revenue increased 12% year over year to $4.2 billion in Q4 2023."
67
+ inputs = tokenizer(text, return_tensors="np", padding="max_length", max_length=512, truncation=True)
68
+ logits = sess.run(None, {"input_ids": inputs["input_ids"], "attention_mask": inputs["attention_mask"]})[0]
69
+
70
+ # SpladePooling: log1p_relu activation (matches OpenSearch v3 models)
71
+ masked = logits * inputs["attention_mask"][..., None]
72
+ pooled = masked.max(axis=1)
73
+ sparse_vector = np.log1p(np.log1p(np.maximum(pooled, 0.0))) # [1, 30522]
74
+
75
+ # Convert to token->weight dict (for inverted index)
76
+ nonzero = np.nonzero(sparse_vector[0])[0]
77
+ token_weights = {tokenizer.decode([tid]): float(sparse_vector[0, tid]) for tid in nonzero}
78
+ print(f"Active dimensions: {len(token_weights)}")
79
+ print(f"Top tokens: {sorted(token_weights.items(), key=lambda x: -x[1])[:10]}")
80
+ ```
81
+
82
+ ## Architecture
83
+
84
+ ```
85
+ Input text
86
+ → Tokenizer (max_length=512)
87
+ → ONNX model (MLM logits) [batch, seq, 30522]
88
+ → SpladePooling: log(1 + log(1 + ReLU(max_over_seq(logits * mask))))
89
+ → Sparse vector [batch, 30522]
90
+ ```
91
+
92
+ Base model: `opensearch-project/opensearch-neural-sparse-encoding-doc-v3-gte` (Alibaba-NLP/new-impl architecture).
93
+
94
+ Fine-tuned on [financial-filings-sparse-retrieval-training](https://huggingface.co/datasets/oneryalcin/financial-filings-sparse-retrieval-training) (18K examples, 2 epochs).
95
+
96
+ ## Export Details
97
+
98
+ - Exported via `torch.onnx.export` (legacy tracer, opset 17)
99
+ - INT8: dynamic quantization via `onnxruntime.quantization.quantize_dynamic` (per-channel, QInt8)
100
+ - Numerical verification: FP32 ONNX max diff vs PyTorch = 0.000057
benchmark.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "seq_len": 512,
3
+ "threads": 1,
4
+ "iters": 30,
5
+ "pytorch_fp32": {
6
+ "p50_ms": 186.2685834785225,
7
+ "p95_ms": 192.7833059511613,
8
+ "mean_ms": 187.10802356363274
9
+ },
10
+ "onnx_fp32": {
11
+ "p50_ms": 211.71175049676094,
12
+ "p95_ms": 218.8744774510269,
13
+ "mean_ms": 211.95321109941383
14
+ },
15
+ "onnx_int8": {
16
+ "p50_ms": 164.41352099354845,
17
+ "p95_ms": 166.8924230907578,
18
+ "mean_ms": 163.78664293248826
19
+ }
20
+ }
config.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "base_model": "opensearch-project/opensearch-neural-sparse-encoding-doc-v3-gte",
3
+ "finetuned_from": "oneryalcin/fin-sparse-encoder-doc-v1",
4
+ "max_seq_length": 512,
5
+ "vocab_size": 30522,
6
+ "activation": "log1p_relu",
7
+ "pooling": "max",
8
+ "splade_postprocess": "log(1 + log(1 + ReLU(max_over_seq(logits * attention_mask))))",
9
+ "files": {
10
+ "model.onnx": "Full precision FP32 ONNX model",
11
+ "model_quantized.onnx": "Dynamic INT8 quantized ONNX model (recommended for CPU)"
12
+ }
13
+ }
model.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:887339947d416cd21db98dbe52ea33c4dba4a214b9e8a138e2ed7048d30665c1
3
+ size 647930964
model_quantized.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:27fd05ec5b30a4ddb3f989caa141ff4eda71a5afda913d2fc61f708f8b281124
3
+ size 166738071
special_tokens_map.json ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cls_token": {
3
+ "content": "[CLS]",
4
+ "lstrip": false,
5
+ "normalized": false,
6
+ "rstrip": false,
7
+ "single_word": false
8
+ },
9
+ "mask_token": {
10
+ "content": "[MASK]",
11
+ "lstrip": false,
12
+ "normalized": false,
13
+ "rstrip": false,
14
+ "single_word": false
15
+ },
16
+ "pad_token": {
17
+ "content": "[PAD]",
18
+ "lstrip": false,
19
+ "normalized": false,
20
+ "rstrip": false,
21
+ "single_word": false
22
+ },
23
+ "sep_token": {
24
+ "content": "[SEP]",
25
+ "lstrip": false,
26
+ "normalized": false,
27
+ "rstrip": false,
28
+ "single_word": false
29
+ },
30
+ "unk_token": {
31
+ "content": "[UNK]",
32
+ "lstrip": false,
33
+ "normalized": false,
34
+ "rstrip": false,
35
+ "single_word": false
36
+ }
37
+ }
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "added_tokens_decoder": {
3
+ "0": {
4
+ "content": "[PAD]",
5
+ "lstrip": false,
6
+ "normalized": false,
7
+ "rstrip": false,
8
+ "single_word": false,
9
+ "special": true
10
+ },
11
+ "100": {
12
+ "content": "[UNK]",
13
+ "lstrip": false,
14
+ "normalized": false,
15
+ "rstrip": false,
16
+ "single_word": false,
17
+ "special": true
18
+ },
19
+ "101": {
20
+ "content": "[CLS]",
21
+ "lstrip": false,
22
+ "normalized": false,
23
+ "rstrip": false,
24
+ "single_word": false,
25
+ "special": true
26
+ },
27
+ "102": {
28
+ "content": "[SEP]",
29
+ "lstrip": false,
30
+ "normalized": false,
31
+ "rstrip": false,
32
+ "single_word": false,
33
+ "special": true
34
+ },
35
+ "103": {
36
+ "content": "[MASK]",
37
+ "lstrip": false,
38
+ "normalized": false,
39
+ "rstrip": false,
40
+ "single_word": false,
41
+ "special": true
42
+ }
43
+ },
44
+ "clean_up_tokenization_spaces": true,
45
+ "cls_token": "[CLS]",
46
+ "do_lower_case": true,
47
+ "extra_special_tokens": {},
48
+ "mask_token": "[MASK]",
49
+ "max_length": 8192,
50
+ "model_max_length": 8192,
51
+ "pad_to_multiple_of": null,
52
+ "pad_token": "[PAD]",
53
+ "pad_token_type_id": 0,
54
+ "padding_side": "right",
55
+ "sep_token": "[SEP]",
56
+ "stride": 0,
57
+ "strip_accents": null,
58
+ "tokenize_chinese_chars": true,
59
+ "tokenizer_class": "DistilBertTokenizer",
60
+ "truncation_side": "right",
61
+ "truncation_strategy": "longest_first",
62
+ "unk_token": "[UNK]"
63
+ }
vocab.txt ADDED
The diff for this file is too large to render. See raw diff