StephanAkkerman commited on
Commit
34ccaeb
·
verified ·
1 Parent(s): 29baf1b

Upload adapter v1

Browse files
README.md ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ base_model: fastino/gliner2.5-base-v1
3
+ library_name: gliner2
4
+ pipeline_tag: token-classification
5
+ language:
6
+ - en
7
+ tags:
8
+ - gliner2
9
+ - lora
10
+ - finance
11
+ - options
12
+ - ner
13
+ ---
14
+
15
+ # options-recognizer-gliner2.5-base-v1
16
+
17
+ LoRA adapter (v1) for [`fastino/gliner2.5-base-v1`](https://huggingface.co/fastino/gliner2.5-base-v1) (194M parameters) that extracts option-contract details from tweets: ticker, strike, option type, expiry, premium and price.
18
+
19
+ Smaller bases are faster, larger ones are more accurate — see the sibling `options-recognizer-*` repos for the other sizes.
20
+
21
+ ## Results (exact-span match, held-out test set `9bbc0005d8a592af`)
22
+
23
+ | label | precision | recall | F1 |
24
+ |---|---|---|---|
25
+ | ticker | 96.8% | 83.1% | 89.5% |
26
+ | strike | 89.6% | 70.1% | 78.6% |
27
+ | option_type | 100.0% | 95.6% | 97.7% |
28
+ | expiry | 99.2% | 67.5% | 80.4% |
29
+ | premium | 98.3% | 65.8% | 78.8% |
30
+ | price | 93.4% | 85.2% | 89.1% |
31
+ | overall | 96.5% | 78.9% | 86.8% |
32
+
33
+ Inference: 10.49 ms/doc (batched, cuda).
34
+
35
+ ## Usage
36
+
37
+ ```python
38
+ import json
39
+ from gliner2 import GLiNER2
40
+ from huggingface_hub import snapshot_download
41
+
42
+ adapter_dir = snapshot_download("StephanAkkerman/options-recognizer-gliner2.5-base-v1")
43
+ cfg = json.load(open(f"{adapter_dir}/recognizer_config.json"))
44
+ model = GLiNER2.from_pretrained(cfg["base_model"])
45
+ model.set_word_splitter(AlnumBoundarySplitter()) # required, see below
46
+ model.load_adapter(adapter_dir)
47
+
48
+ result = model.extract_entities(
49
+ "$AAPL 350 C 11/06/2026 $1.2M 4.37avg",
50
+ cfg["entity_descriptions"],
51
+ threshold=cfg["threshold"],
52
+ )
53
+ ```
54
+
55
+ Recommended threshold: **0.75**.
56
+
57
+ ## Required word splitter
58
+
59
+ The adapter was trained with a custom word splitter that breaks between letters and digits, so `1.58avg` and `11/20exp` tokenize cleanly. Define it before loading the adapter, or accuracy drops sharply:
60
+
61
+ ```python
62
+ import re
63
+
64
+ class AlnumBoundarySplitter:
65
+ """GLiNER2 word splitter that also breaks between letters and digits.
66
+
67
+ The stock splitter keeps whole words together, so in ``1.58avg``, ``11/20exp``
68
+ and ``375C`` the gold span ends mid-word and can neither be trained on nor
69
+ predicted. Splitting at letter/digit boundaries makes those spans
70
+ word-aligned. Dates (``10/16/2026``) and numbers with decimals or thousands
71
+ separators (``5.1``, ``18,140``) stay whole so a fragment such as the ``10``
72
+ of a date can never be proposed as a strike. Must be used identically at
73
+ train and inference time.
74
+ """
75
+
76
+ _PATTERN = re.compile(
77
+ r"""(?:https?://[^\s]+|www\.[^\s]+)
78
+ |[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}
79
+ |@[a-z0-9_]+
80
+ |[^\W\d_]+(?:[-_][^\W\d_]+)*
81
+ |\d{1,2}/\d{1,2}(?:/\d{2,4})?(?![\d,.]\d)
82
+ |\d+(?:[.,]\d+)*
83
+ |\S""",
84
+ re.VERBOSE | re.IGNORECASE,
85
+ )
86
+
87
+ def __call__(self, text, lower=True):
88
+ for m in self._PATTERN.finditer(text):
89
+ token = m.group()
90
+ yield (token.lower() if lower else token), m.start(), m.end()
91
+ ```
adapter_config.json ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "alora_invocation_tokens": null,
3
+ "alpha_pattern": {},
4
+ "arrow_config": null,
5
+ "auto_mapping": {
6
+ "base_model_class": "BoundaryExtractor",
7
+ "parent_library": "gliner2.models.boundary.engine"
8
+ },
9
+ "base_model_name_or_path": "fastino/gliner2.5-base-v1",
10
+ "bias": "none",
11
+ "corda_config": null,
12
+ "ensure_weight_tying": false,
13
+ "eva_config": null,
14
+ "exclude_modules": null,
15
+ "fan_in_fan_out": false,
16
+ "inference_mode": true,
17
+ "init_lora_weights": true,
18
+ "kasa_config": null,
19
+ "layer_replication": null,
20
+ "layers_pattern": null,
21
+ "layers_to_transform": null,
22
+ "loftq_config": {},
23
+ "lora_alpha": 64,
24
+ "lora_bias": false,
25
+ "lora_dropout": 0.1,
26
+ "lora_ga_config": null,
27
+ "megatron_config": null,
28
+ "megatron_core": "megatron.core",
29
+ "modules_to_save": null,
30
+ "monteclora_config": null,
31
+ "peft_type": "LORA",
32
+ "peft_version": "0.21.2",
33
+ "qalora_group_size": 16,
34
+ "r": 32,
35
+ "rank_pattern": {},
36
+ "revision": null,
37
+ "target_modules": [
38
+ "query_proj",
39
+ "value_proj",
40
+ "key_proj",
41
+ "dense"
42
+ ],
43
+ "target_parameters": null,
44
+ "task_type": null,
45
+ "trainable_token_indices": null,
46
+ "use_bdlora": null,
47
+ "use_dora": false,
48
+ "use_qalora": false,
49
+ "use_rslora": false,
50
+ "velora_config": null
51
+ }
adapter_model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:baa60f8984ec7857f3aae202be8fc5f0652c72e56802719851c4b7c1d1a9388d
3
+ size 21254736
recognizer_config.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "base_model": "fastino/gliner2.5-base-v1",
3
+ "adapter_version": 1,
4
+ "labels": [
5
+ "ticker",
6
+ "strike",
7
+ "option_type",
8
+ "expiry",
9
+ "premium",
10
+ "price"
11
+ ],
12
+ "entity_descriptions": {
13
+ "ticker": "The stock or ETF symbol an option contract is written on, usually 1-5 letters and often preceded by a dollar sign (e.g., $AAPL, SPY, $T). MUST NOT be a company name, an @handle, or slang (YOLO, NFA, OTM, ITM).",
14
+ "strike": "The strike price of an option contract, e.g. 350, 162.5, or $1300 in '$1300 calls'. MUST NOT be the stock's current price, a premium or per-contract price, a date, or a percentage.",
15
+ "option_type": "Whether the contract is a call or a put, in any written form: C, P, call, calls, put, puts, c, p. Only the call/put word itself, not words like buyer or seller.",
16
+ "expiry": "The expiration date of an option contract: 10/16, 11/06/2026, 6/17/27, November 20, 2026, December, or relative like '2 days'. MUST NOT be the date a report was posted (e.g. the 10/2 in '10/2 Notable Flow').",
17
+ "premium": "The total dollar size of the trade, e.g. $1.2M, $993K, 23 million. MUST NOT be a strike, the per-contract price, or the stock price.",
18
+ "price": "The per-contract price or average fill, e.g. .15 in '@ .15' or 4.37 in '4.37avg'. Only the number. MUST NOT be a strike, premium, or the underlying's stock price."
19
+ },
20
+ "threshold": 0.75,
21
+ "word_splitter": "alnum-v2"
22
+ }