cp500 commited on
Commit
fae24bf
Β·
verified Β·
1 Parent(s): f5dfbf3

Upload js/README.md with huggingface_hub

Browse files
Files changed (1) hide show
  1. js/README.md +244 -0
js/README.md ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # @cp500/infon-coref
2
+
3
+ Multilingual coreference resolution in the browser or Node, via ONNX.
4
+
5
+ The trained model is a pointer-network coref resolver fine-tuned on
6
+ top of a multilingual MiniLM-L12 distilled from XLM-R. It handles
7
+ **English, Japanese, Korean, Thai, and Chinese** β€” replaces
8
+ English-only [fastcoref](https://github.com/shon-otmazgin/fastcoref)
9
+ for use cases that need multilingual coverage.
10
+
11
+ The model artefacts live at
12
+ [**cp500/infon-coref-pointer**](https://huggingface.co/cp500/infon-coref-pointer)
13
+ on the Hugging Face Hub. This package is the JavaScript client that
14
+ loads them.
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ npm install @cp500/infon-coref onnxruntime-web
20
+ # or for Node:
21
+ npm install @cp500/infon-coref onnxruntime-node
22
+ ```
23
+
24
+ The ONNX runtime is a **peer dependency** so you only install the one
25
+ your environment needs. ``@huggingface/tokenizers`` is **optional**;
26
+ if installed, we use its WASM SentencePiece tokenizer (faster and
27
+ fully spec-compliant). Otherwise the package falls back to a minimal
28
+ pure-JS tokenizer that handles the XLM-R vocabulary.
29
+
30
+ ## Quick start (browser)
31
+
32
+ ```ts
33
+ import { InfonCorefModel } from '@cp500/infon-coref';
34
+
35
+ const model = await InfonCorefModel.fromHub('cp500/infon-coref-pointer', {
36
+ precision: 'fp16', // 'fp16' (default, ~235 MB) or 'fp32' (~470 MB)
37
+ device: 'auto', // tries WebGPU, falls back to WASM
38
+ });
39
+
40
+ const result = await model.resolve(
41
+ 'Toyota announced a partnership with Panasonic on battery technology. ' +
42
+ 'The Japanese automaker said the deal is worth $250 million.'
43
+ );
44
+
45
+ for (const cluster of result.clusters) {
46
+ const surfaces = cluster.map(i => result.mentions[i].text);
47
+ console.log(surfaces.join(' ↔ '));
48
+ // Toyota ↔ The Japanese automaker
49
+ }
50
+ ```
51
+
52
+ ## Quick start (Node)
53
+
54
+ ```ts
55
+ import { InfonCorefModel } from '@cp500/infon-coref';
56
+
57
+ // Same API as fromHub, but reads from local files (e.g. after a
58
+ // huggingface-cli download).
59
+ const model = await InfonCorefModel.fromLocal('./models/infon-coref/');
60
+ const result = await model.resolve('Toyota e Panasonic anunciaram...');
61
+ ```
62
+
63
+ ## What you get back
64
+
65
+ ```ts
66
+ interface CorefResult {
67
+ text: string; // original input, unchanged
68
+ tokens: Token[]; // wordpieces with char offsets
69
+ mentions: Mention[]; // detected mentions in document order
70
+ clusters: number[][]; // clusters[c] = list of mention indices
71
+ timing: {
72
+ tokenize: number;
73
+ backbone: number;
74
+ bioDecode: number;
75
+ scorer: number;
76
+ total: number; // ms
77
+ };
78
+ }
79
+
80
+ interface Mention {
81
+ start: number; // wordpiece index, inclusive
82
+ end: number; // wordpiece index, inclusive
83
+ charStart: number; // char offset in source text
84
+ charEnd: number;
85
+ text: string; // literal substring of source text
86
+ cluster: number; // -1 for singleton
87
+ antecedent: number; // 0-based mention index, -1 = no antecedent
88
+ }
89
+ ```
90
+
91
+ ## Languages
92
+
93
+ Trained on synthetic Bedrock/Claude-generated data balanced across:
94
+
95
+ | Code | Language |
96
+ |------|----------------|
97
+ | `en` | English |
98
+ | `ja` | Japanese |
99
+ | `ko` | Korean |
100
+ | `th` | Thai |
101
+ | `zh` | Chinese (Simplified) |
102
+
103
+ The XLM-R backbone covers ~100 languages but mention detection +
104
+ pointer-net heads were only trained on these 5. Other languages may
105
+ work via zero-shot transfer; verify on your domain before shipping.
106
+
107
+ ## API
108
+
109
+ ### `InfonCorefModel.fromHub(repo, options?)`
110
+
111
+ Load model artefacts from a Hugging Face repo. Downloads (and caches
112
+ in the browser Cache API) ``meta.json``, the chosen ONNX backbone,
113
+ the mention scorer, and ``tokenizer.json``.
114
+
115
+ | Option | Type | Default | Notes |
116
+ |----------------|-----------------------------------------|-----------|-------|
117
+ | `precision` | `'fp32' \| 'fp16'` | `'fp16'` | FP16 halves the download. Falls back to FP32 if FP16 is missing in the repo. |
118
+ | `device` | `'auto' \| 'webgpu' \| 'wasm' \| 'cpu' \| 'cuda'` | `'auto'` | Browser auto-prefers WebGPU. |
119
+ | `maxLength` | `number` | `256` | Truncates inputs longer than N wordpieces. |
120
+ | `bioThreshold` | `number` | none | If set, suppresses low-confidence span detections. `0.7` is a common stricter setting. |
121
+ | `revision` | `string` | `'main'` | HF branch/tag/commit-SHA pin. |
122
+ | `debug` | `boolean` | `false` | Logs per-stage timings to `console.debug`. |
123
+
124
+ ### `InfonCorefModel.fromLocal(baseUrl, options?)`
125
+
126
+ Same as `fromHub` but loads files relative to a base URL or
127
+ filesystem path. Browser: `baseUrl` is a URL prefix
128
+ (`/models/coref/`). Node: a directory path (`./models/coref/`).
129
+
130
+ The directory must contain:
131
+
132
+ ```
133
+ meta.json
134
+ tokenizer.json
135
+ onnx/backbone_bio.onnx (and .onnx.data sidecar if present)
136
+ onnx/backbone_bio_fp16.onnx
137
+ onnx/mention_scorer.onnx
138
+ onnx/mention_scorer_fp16.onnx
139
+ ```
140
+
141
+ ### `model.resolve(text, options?)`
142
+
143
+ Run end-to-end coref on a single document. Returns
144
+ [`CorefResult`](#what-you-get-back).
145
+
146
+ `options` accepts the same per-call overrides as `fromHub`'s
147
+ `maxLength`, `bioThreshold`, `debug`.
148
+
149
+ ## Power-user exports
150
+
151
+ If you want to swap one stage of the pipeline (e.g. a custom
152
+ tokenizer or a different ORT runtime), the helpers are exported
153
+ individually:
154
+
155
+ ```ts
156
+ import {
157
+ buildPairs, // mention M β†’ flat (pair_i, pair_j) tensors
158
+ decodeBio, // BIO logits β†’ wordpiece spans
159
+ groupClusters, // antecedent decisions β†’ union-find clusters
160
+ loadTokenizer, // SentencePiece JSON β†’ Tokenizer
161
+ fetchHubFile, // HF Hub fetch + browser-cache
162
+ } from '@cp500/infon-coref';
163
+ ```
164
+
165
+ These match the Python reference implementation in
166
+ [`scripts/coref_onnx_experiment.py`](https://github.com/cp500/overlord/blob/main/infon/scripts/coref_onnx_experiment.py)
167
+ exactly β€” useful when comparing a Python/TS pipeline at the
168
+ intermediate-tensor level.
169
+
170
+ ## Architecture
171
+
172
+ ```
173
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
174
+ β”‚ text β”‚
175
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
176
+ β–Ό
177
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
178
+ β”‚ SentencePiece tokenize β”‚ tokenizer.json (XLM-R vocab)
179
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
180
+ β–Ό input_ids, attention_mask
181
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
182
+ β”‚ backbone_bio.onnx β”‚ MiniLM-L12 (12 layers, H=384)
183
+ β”‚ β€’ XLM-R encoder β”‚ + 3-class BIO head
184
+ β”‚ β€’ bio_logits (T,3) β”‚
185
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
186
+ β”‚ β”‚
187
+ β”‚ β–Ό bio_logits β†’ run-length decode β†’ spans
188
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
189
+ β”‚ β”‚ decodeBio (TS) β”‚
190
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
191
+ β”‚ β–Ό span_starts, span_ends
192
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
193
+ β”‚ β”‚ buildPairs (TS) β”‚
194
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
195
+ β”‚ β–Ό pair_i, pair_j (triangular)
196
+ β–Ό β–Ό
197
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
198
+ β”‚ mention_scorer.onnx β”‚ gather + segment-mean pool +
199
+ β”‚ β€’ pair_scores (P,) β”‚ 3-vector pair MLP
200
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
201
+ β–Ό
202
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
203
+ β”‚ pickAntecedents (TS) β”‚
204
+ β”‚ + groupClusters (TS) β”‚
205
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
206
+ β–Ό
207
+ CorefResult
208
+ ```
209
+
210
+ The split between the two ONNX graphs exists so the BIO head can
211
+ share computation with the backbone (one forward pass), while the
212
+ mention scorer can be re-run with different `(pair_i, pair_j)`
213
+ batches without recomputing hidden states. It also keeps each ONNX
214
+ file's input signature simple enough to trace cleanly.
215
+
216
+ ## Performance ballpark
217
+
218
+ Numbers from a 2024 M1 Pro Macbook on a 110-token English document:
219
+
220
+ | Stage | WASM (FP16) | WebGPU (FP16) | Node CPU (FP16) |
221
+ |-----------|-------------|---------------|-----------------|
222
+ | Tokenize | 4 ms | 4 ms | 2 ms |
223
+ | Backbone | 220 ms | 70 ms | 90 ms |
224
+ | BIO | <1 ms | <1 ms | <1 ms |
225
+ | Scorer | 5 ms | 4 ms | 2 ms |
226
+ | **Total** | **~230 ms** | **~80 ms** | **~95 ms** |
227
+
228
+ First call adds ~2-4 s for ONNX session warmup. The Cache API in
229
+ browsers persists the downloaded model so warmup-after-reload is
230
+ limited to session creation.
231
+
232
+ ## License
233
+
234
+ Apache 2.0. The trained weights at `cp500/infon-coref-pointer` carry
235
+ the same license; the underlying MiniLM-L12 backbone is also Apache
236
+ 2.0.
237
+
238
+ ## Status
239
+
240
+ Alpha. The API is stable enough to integrate behind your own
241
+ abstraction; expect minor breaking changes on the public class
242
+ shape until 1.0.
243
+
244
+ Issue tracker: https://github.com/cp500/infon-coref-js/issues