gpu-sankhya 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +164 -45
- package/dist/charset.d.ts +1 -1
- package/dist/core.d.ts +25 -0
- package/dist/decode.d.ts +15 -0
- package/dist/index.d.ts +16 -2
- package/dist/index.js +8 -5
- package/dist/types.d.ts +119 -1
- package/dist/weights.d.ts +15 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# gpu-sankhya
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/gpu-sankhya)
|
|
4
|
-
[](https://www.npmjs.com/package/gpu-sankhya?activeTab=code)
|
|
5
5
|
[](./LICENSE)
|
|
6
6
|
[](https://athrvk.github.io/gpu-sankhya/)
|
|
7
7
|
|
|
@@ -21,9 +21,10 @@ never predicts the value directly, so the arithmetic can't drift from the
|
|
|
21
21
|
grammar (prefix semantics, additive descending units, multiplicative
|
|
22
22
|
ascending units like `das hazaar crore` = 10,000 × 1 crore = 1e11, etc).
|
|
23
23
|
|
|
24
|
-
Ships with a small (
|
|
25
|
-
in the package — `import { parse }
|
|
26
|
-
network fetch. Zero runtime
|
|
24
|
+
Ships with a small (47.2 KB gzipped, 80.8 KB raw `dist/index.js`)
|
|
25
|
+
int8-quantized default model inlined in the package — `import { parse }
|
|
26
|
+
from "gpu-sankhya"` works with no network fetch. Zero runtime
|
|
27
|
+
dependencies.
|
|
27
28
|
|
|
28
29
|
Model training lives in `python/` (a separate, actively-trained
|
|
29
30
|
component); this package is the runtime that loads its exported weights.
|
|
@@ -129,6 +130,23 @@ interface Sankhya {
|
|
|
129
130
|
actually obtained. Result is cached, so repeated calls only probe once.
|
|
130
131
|
`parseBatch`'s `"auto"` backend uses this (not `isWebGPUAvailable()`)
|
|
131
132
|
to decide whether to try the GPU path.
|
|
133
|
+
- **Non-string input**: `parse`, `parseBatch`, and `inspect` all tolerate
|
|
134
|
+
a non-string argument (`null`, `undefined`, a number, object, array,
|
|
135
|
+
boolean, ...) by treating it as no input rather than throwing —
|
|
136
|
+
`parse(null)` returns `[]` instead of crashing.
|
|
137
|
+
- **`inspect(text) => Inspection`** — synchronous CPU inspection of the
|
|
138
|
+
raw model output before decode/repair: `{ text, chars: [{ch, bio,
|
|
139
|
+
bioProb, cls, clsId}], spans, ms }`, one entry per character with its
|
|
140
|
+
argmax BIO tag, BIO softmax probability, and predicted class. Useful
|
|
141
|
+
for debugging misclassifications or building a "what did the model
|
|
142
|
+
actually see" view (this is what powers the demo's per-character
|
|
143
|
+
panel); `parse()`'s decoded spans are the thing to use for normal
|
|
144
|
+
consumption.
|
|
145
|
+
- **`modelInfo() => ModelInfo`** — info about the currently loaded
|
|
146
|
+
default model: `{ version, params, channels, embedDim, vocab, classes,
|
|
147
|
+
layers: [{k, dilation, residual}] }`.
|
|
148
|
+
- **`CLASSES`** — the exported array of semantic token class names (the
|
|
149
|
+
same strings that appear in `Sankhya.classes` and `Inspection.chars[].cls`).
|
|
132
150
|
- **`normalizeText(text) => string`** — the exact normalization
|
|
133
151
|
`parse`/`parseBatch` apply before char-encoding (Unicode NFC, then
|
|
134
152
|
Devanagari digits U+0966-U+096F mapped 1:1 to ASCII `"0"`-`"9"`, then
|
|
@@ -156,52 +174,85 @@ interface Sankhya {
|
|
|
156
174
|
|
|
157
175
|
### Why CPU by default
|
|
158
176
|
|
|
159
|
-
One inference is small —
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
benchmark
|
|
172
|
-
|
|
177
|
+
One inference is small — a 5-layer, 48-channel dilated/residual char
|
|
178
|
+
CNN, 39,579 parameters — and `parse()` runs in about 3.6 ms p50 (60-char
|
|
179
|
+
input) in plain JS; `parseBatch` on CPU averages about 4.0 ms/string over
|
|
180
|
+
500 strings. A WebGPU dispatch has fixed overhead of a few milliseconds
|
|
181
|
+
(device/pipeline setup, buffer upload, queue submit, readback), which
|
|
182
|
+
dwarfs that per-string cost. So the GPU only pays off once you're
|
|
183
|
+
amortizing that overhead over a batch — hundreds of strings at once —
|
|
184
|
+
which is exactly what `parseBatch` does with `backend: "auto"`/`"webgpu"`;
|
|
185
|
+
`parse()` stays CPU-only and synchronous on purpose.
|
|
186
|
+
|
|
187
|
+
The WebGPU path has been verified on a real GPU in desktop Chrome with
|
|
188
|
+
the shipped `v2` model (residual layers included): on the demo page's
|
|
189
|
+
batch benchmark (500 varied strings) it matches the CPU backend
|
|
190
|
+
span-for-span (500/500) and runs about 1.9x faster (CPU 1.66 ms/string,
|
|
191
|
+
WebGPU 0.88 ms/string). The demo's benchmark re-runs the CPU/WebGPU
|
|
192
|
+
comparison on every click, so any regression shows up as a mismatch
|
|
193
|
+
count rather than a silent wrong answer.
|
|
173
194
|
|
|
174
195
|
## Accuracy
|
|
175
196
|
|
|
176
|
-
The bundled default model:
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
197
|
+
The bundled default model (arch `v2`): 39,579 parameters, 5 conv layers
|
|
198
|
+
over 16-dim char embeddings — a plain kernel-5 layer, then four residual
|
|
199
|
+
kernel-3 layers with dilations 1/2/4/8 (`y = relu(conv(x)) + x`), 48
|
|
200
|
+
channels, ±17-character receptive field — over a 114-character vocab
|
|
201
|
+
(union of the `hi_latn` and `hi_deva` packs), 120 output classes. Trained
|
|
202
|
+
20 epochs on 200,000 synthetic examples generated from both language
|
|
203
|
+
packs' grammars, mixed 0.55/0.45 with a 10% cross-pack share, plus
|
|
204
|
+
out-of-vocab "unk noise" augmentation so the model has actually seen
|
|
205
|
+
`<unk>` characters (emoji, CJK, Cyrillic, other symbols) during training
|
|
206
|
+
(see `python/README.md`). An older `v1` preset (the previously shipped
|
|
207
|
+
4-layer, non-residual, 32-channel stack) is still loadable by both the
|
|
208
|
+
Python and JS runtimes for anyone using older exported weights.
|
|
182
209
|
|
|
183
210
|
On synthetic validation data (drawn from the same generator/templates as
|
|
184
|
-
training): 0.
|
|
211
|
+
training): 0.925 value accuracy. This number is optimistic — it's testing
|
|
185
212
|
the model on its own distribution.
|
|
186
213
|
|
|
187
214
|
On two hand-written gold sets, written independently of the generator —
|
|
188
|
-
`python/tests/gold.jsonl` (romanised Hindi,
|
|
189
|
-
`python/tests/gold_deva.jsonl` (Devanagari Hindi,
|
|
215
|
+
`python/tests/gold.jsonl` (romanised Hindi, 214 sentences / 188 spans)
|
|
216
|
+
and `python/tests/gold_deva.jsonl` (Devanagari Hindi, 182 sentences / 151
|
|
190
217
|
spans) — evaluated against the shipped int8-quantized weights:
|
|
191
218
|
|
|
192
219
|
| gold set | examples | spans | value accuracy | span precision | span recall | span F1 |
|
|
193
220
|
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
|
|
194
|
-
| gold.jsonl (romanised) |
|
|
195
|
-
| gold_deva.jsonl (Devanagari) |
|
|
196
|
-
| combined |
|
|
221
|
+
| gold.jsonl (romanised) | 214 | 188 | 0.9255 | 0.9167 | 0.9362 | 0.9263 |
|
|
222
|
+
| gold_deva.jsonl (Devanagari) | 182 | 151 | 0.9735 | 0.9737 | 0.9801 | 0.9769 |
|
|
223
|
+
| combined | 396 | 339 | 0.9469 | 0.9419 | 0.9558 | 0.9488 |
|
|
224
|
+
|
|
225
|
+
Negatives (zero-gold-span examples, 73 total): 0 false positives.
|
|
226
|
+
Miss summary: missed 2, spurious 7, wrong value 3, wrong boundary 13.
|
|
227
|
+
Per-category value accuracy: digits 0.967, words 0.940, prefix 0.926,
|
|
228
|
+
range 0.917, currency 1.0, multi_unit 0.952, symbol_unit 0.970,
|
|
229
|
+
mixed_script 1.0, long 0.80.
|
|
230
|
+
|
|
231
|
+
For comparison, the previous shipped weights scored, on this same
|
|
232
|
+
enlarged gold set: 0.9096 (romanised) / 0.9603 (Devanagari) / 0.9322
|
|
233
|
+
combined value acc, F1 0.9258, 4/73 negatives false positives (5.5%).
|
|
234
|
+
(Their numbers on the older, smaller 353-example gold set were 0.952 /
|
|
235
|
+
0.986 / 0.968 — the new gold set is deliberately harder: it adds
|
|
236
|
+
conjunction-joined multi-span sentences, trailing-cardinal chains,
|
|
237
|
+
possessive noise, in-context typos, cardinal spelling variants, and 18
|
|
238
|
+
more negative examples.) This round also ran a 198-case hand-written
|
|
239
|
+
edge-case probe across 12 categories (whitespace/short input, long
|
|
240
|
+
input, Unicode, numeric forms, prefix semantics, compound units,
|
|
241
|
+
currency, negatives, multi-span strings, noise/typos, Devanagari
|
|
242
|
+
equivalents, API contract) targeting decoder and boundary bugs rather
|
|
243
|
+
than the gold distribution itself; the fixes below took it from 146
|
|
244
|
+
pass / 17 spurious / 8 wrong value / 7 crashes to 179 pass / 0 crashes /
|
|
245
|
+
5 spurious / 1 wrong value (remaining misses are mostly boundary/range
|
|
246
|
+
edge cases, tracked below).
|
|
197
247
|
|
|
198
248
|
**The gold numbers are the ones to trust.** Known miss categories, in rough
|
|
199
249
|
order of frequency:
|
|
200
250
|
|
|
251
|
+
- wrong span boundaries on multi-span/range/connector phrases (the
|
|
252
|
+
largest single category this round)
|
|
253
|
+
- wrong value on a handful of prefix/compound constructs
|
|
201
254
|
- unusual typos the noise model doesn't cover (e.g. "croer" for "crore")
|
|
202
|
-
- possessive apostrophes ("do lakh's")
|
|
203
255
|
- long multi-term/mixed-numeral constructs ("three n half lakh", "50M")
|
|
204
|
-
- multi-number range phrases ("तीस पैंतीस हज़ार", "paanch se sadhe saat lakh")
|
|
205
256
|
- occasional spurious spans triggered by unfamiliar words near number-ish
|
|
206
257
|
context
|
|
207
258
|
|
|
@@ -215,7 +266,7 @@ from `python/` (see `python/README.md`).
|
|
|
215
266
|
Devanagari digits U+0966-U+096F mapped to ASCII `"0"`-`"9"`, then
|
|
216
267
|
lowercased — byte-identical to the Python reference) and char-encoded
|
|
217
268
|
against the model's vocab (unknown chars map to `<unk>`).
|
|
218
|
-
2. A
|
|
269
|
+
2. A dilated/residual conv1d stack (see Accuracy above) produces, per
|
|
219
270
|
character, a 3-way BIO logit (O/B/I) and a class logit over the
|
|
220
271
|
semantic token vocabulary (prefix words, cardinals, units, digits,
|
|
221
272
|
separators, misc).
|
|
@@ -244,15 +295,47 @@ Raw per-character BIO/class predictions are cleaned up before evaluation:
|
|
|
244
295
|
majority vote over character-type sub-runs (fixes a stray misclassified
|
|
245
296
|
character inside an otherwise-consistent digit or letter run), plus a
|
|
246
297
|
few punctuation-specific rules.
|
|
298
|
+
- **Word integrity**: a `UNIT_`/`PFX_`/`CARD_` token must line up with the
|
|
299
|
+
letter-word it sits in — a letters-run that's only partially meaningful
|
|
300
|
+
(some characters fell back to `O`) has all of it retagged `O` (e.g.
|
|
301
|
+
`"10 km"`), while a run legitimately split into several back-to-back
|
|
302
|
+
meaningful sub-words is left alone (e.g. `"dedhlakh"` = `PFX_DEDH` +
|
|
303
|
+
`UNIT_LAKH`). A one-character symbol unit (`k`/`K`/`l`/`L`) is additionally
|
|
304
|
+
only valid when the next character isn't a letter, so `"20k logon"`
|
|
305
|
+
keeps its `k` but `"10 km"`'s `k` doesn't survive alone either.
|
|
306
|
+
- **Bare-digits gate**: a span whose only meaningful tokens are digits (no
|
|
307
|
+
unit/prefix/cardinal word at all) with no detected currency marker is
|
|
308
|
+
dropped only when it's short and ungrouped (≤4 digits, no comma — route
|
|
309
|
+
numbers, OTPs, years: `"1"`, `"route 66"`, `"OTP 4521"`, `"2024"`) or very
|
|
310
|
+
long (≥10 digits — phone numbers: `"9876543210"`). Everything else is
|
|
311
|
+
kept as a plain (unitless) amount — `"15000"`, `"1,00,000"`,
|
|
312
|
+
`"2,50,00,000"` all parse; `"₹75"` / `"Rs 2,50,000/-"` / `"1200 rupees"`
|
|
313
|
+
still parse with `currency: "INR"`. The currency-marker look-ahead
|
|
314
|
+
scans 8 characters past the amount for a trailing marker word (up from
|
|
315
|
+
a shorter window that missed `"1200 rupees"` — `"rupees"` alone runs to
|
|
316
|
+
6 characters plus the leading space).
|
|
317
|
+
- **Range-connector repair**: a bare `-`/`–`/`—`/`/` between two amounts
|
|
318
|
+
becomes a `RANGE` tag (spaces around it stay `SEP`) when the left side
|
|
319
|
+
can end an amount by itself and the right side can start a fresh one
|
|
320
|
+
(`"2 lakh/3 lakh"`, `"दो-तीन लाख"`) — but not when it's really one
|
|
321
|
+
compound number, e.g. a prefix glued straight to a unit (`"dedh-lakh"`
|
|
322
|
+
stays one span, not a range).
|
|
323
|
+
- **Possessive trim**: a trailing `'s`/`’s` (1-2 letters) is stripped from
|
|
324
|
+
the end of a word and excluded from the span (`"2 lakh's"` → `"2 lakh"`).
|
|
247
325
|
- **Confidence filter**: a span's confidence is the mean of the max BIO
|
|
248
326
|
softmax probability per character; spans below 0.5 are dropped.
|
|
249
327
|
- Only after all of the above does the deterministic arithmetic core run
|
|
250
|
-
on the resulting token sequence
|
|
328
|
+
on the resulting token sequence, which also treats a `RANGE` connector
|
|
329
|
+
between two amounts that BOTH already carry a unit and are strictly
|
|
330
|
+
*descending* (e.g. `"ek lakh dus hazaar"` mistagged `RANGE` on the
|
|
331
|
+
space) as one additive amount rather than a `[low, high]` range —
|
|
332
|
+
genuine ranges (only one side has a unit, or both do but ascending) are
|
|
333
|
+
unaffected.
|
|
251
334
|
|
|
252
335
|
One more detail that matters more than it looks like it should: the
|
|
253
|
-
runtime right-pads the character-id array with
|
|
336
|
+
runtime right-pads the character-id array with 24 pad tokens before
|
|
254
337
|
running the forward pass (mirroring `python/sankhya/np_infer.py`'s
|
|
255
|
-
`pad_ids`/`PAD_TAIL=
|
|
338
|
+
`pad_ids`/`PAD_TAIL=24`), because training always right-pads every
|
|
256
339
|
example to the model's max length the same way. Running a short, tightly
|
|
257
340
|
cropped input (e.g. the bare 4 characters of `"2.5L"`) without that
|
|
258
341
|
padding measurably corrupts predictions — the model was never trained on
|
|
@@ -274,16 +357,30 @@ outputs are discarded; only the real characters' predictions are used.
|
|
|
274
357
|
- **Offsets are into the normalized string.** `parse()`'s `start`/`end`
|
|
275
358
|
index `normalizeText(text)`, not the raw input, in the rare case NFC
|
|
276
359
|
normalization changes the string's length (see `normalizeText` in the
|
|
277
|
-
API section above)
|
|
360
|
+
API section above); in JS, an astral (surrogate-pair) character such as
|
|
361
|
+
an emoji also counts as two UTF-16 units in those offsets, same as any
|
|
362
|
+
other JS string indexing.
|
|
278
363
|
- Text longer than 128 characters is processed with a sliding window
|
|
279
364
|
(128-char windows, 16-char overlap) and results are merged/deduplicated
|
|
280
365
|
by span; extremely long inputs may still miss a span that straddles a
|
|
281
366
|
window boundary in an unlucky way.
|
|
367
|
+
- **Bare single cardinal words without a unit are not reliably
|
|
368
|
+
extracted.** `"unnasi"` alone produces no span, while `"unnasi hazaar"`
|
|
369
|
+
correctly resolves to 79000 — a bare number word needs a unit, prefix,
|
|
370
|
+
or digit context to be tagged.
|
|
371
|
+
- **Long multi-term ranges still split incorrectly.** Constructs like
|
|
372
|
+
`"paanch se sadhe saat lakh"` (a range where one side itself carries a
|
|
373
|
+
prefix word) are not reliably decoded as a single range.
|
|
374
|
+
- **Fullwidth and Arabic-Indic digits are not normalised.** Only
|
|
375
|
+
Devanagari digits (U+0966-U+096F) are mapped by `normalizeText`;
|
|
376
|
+
fullwidth (`2`) and Arabic-Indic (`٢`) digit forms are left as unknown
|
|
377
|
+
characters, so a phrase like `"2 lakh"` loses the digit and falls back
|
|
378
|
+
to the unit's default value.
|
|
282
379
|
- Model quality: see Accuracy above. The known miss categories there
|
|
283
|
-
(
|
|
284
|
-
occasional spurious spans) are model-quality
|
|
285
|
-
arithmetic core, which is unit-tested directly
|
|
286
|
-
model in `test/core.test.ts`.
|
|
380
|
+
(wrong span boundaries on multi-span/range phrases, unusual typos,
|
|
381
|
+
long multi-term ranges, occasional spurious spans) are model-quality
|
|
382
|
+
issues, not bugs in the arithmetic core, which is unit-tested directly
|
|
383
|
+
and independently of the model in `test/core.test.ts`.
|
|
287
384
|
|
|
288
385
|
## Repository layout
|
|
289
386
|
|
|
@@ -296,7 +393,10 @@ outputs are discarded; only the real characters' predictions are used.
|
|
|
296
393
|
(`test/fixtures/parity.jsonl`, `decoded.jsonl` — see
|
|
297
394
|
`python/README.md`'s "Ship to the npm package" section).
|
|
298
395
|
- `bench/` — `parse()`/`parseBatch()` latency benchmarks.
|
|
299
|
-
- `demo/` —
|
|
396
|
+
- `demo/` — an interactive demo: live parse as you type, a per-character
|
|
397
|
+
model-internals view (`inspect()`), batch benchmark controls (CPU vs
|
|
398
|
+
WebGPU), a raw-JSON view of results, a theme toggle, and shareable
|
|
399
|
+
state via URL hash.
|
|
300
400
|
- `python/sankhya/` — `classes.py` (shared class vocabulary), `core.py`
|
|
301
401
|
(the deterministic arithmetic core), `langs/` (language packs, e.g.
|
|
302
402
|
`hi_latn.py`), `noise_latn.py` (typo/spelling-variance injection),
|
|
@@ -337,9 +437,11 @@ npm run bench # parse() and parseBatch() latency
|
|
|
337
437
|
npm run size # gzipped dist/index.js size
|
|
338
438
|
```
|
|
339
439
|
|
|
340
|
-
See `demo/index.html` for
|
|
341
|
-
|
|
342
|
-
|
|
440
|
+
See `demo/index.html` for the full interactive demo (live parse,
|
|
441
|
+
per-character model view, benchmark controls, JSON view, theme toggle,
|
|
442
|
+
shareable hash) — it imports `dist/index.js` directly (no build step
|
|
443
|
+
needed beyond `npm run build`). Live at
|
|
444
|
+
https://athrvk.github.io/gpu-sankhya/.
|
|
343
445
|
|
|
344
446
|
## Releasing
|
|
345
447
|
|
|
@@ -363,3 +465,20 @@ npmjs.com for this to work: package page -> Settings -> Trusted publisher,
|
|
|
363
465
|
with Organization/user `athrvk`, Repository `gpu-sankhya`, Workflow
|
|
364
466
|
filename `publish.yml`. The first release was published manually with
|
|
365
467
|
`npm publish`.
|
|
468
|
+
|
|
469
|
+
### Publishing to Hugging Face
|
|
470
|
+
|
|
471
|
+
The `.github/workflows/huggingface.yml` workflow mirrors the shipped model,
|
|
472
|
+
the demo, and the gold evaluation sets to Hugging Face:
|
|
473
|
+
|
|
474
|
+
- model: https://huggingface.co/athrvk/gpu-sankhya
|
|
475
|
+
- demo Space: https://huggingface.co/spaces/athrvk/gpu-sankhya-demo
|
|
476
|
+
- dataset: https://huggingface.co/datasets/athrvk/gpu-sankhya-gold
|
|
477
|
+
|
|
478
|
+
It runs on `workflow_dispatch` (choose `all`/`model`/`space`/`dataset`) and
|
|
479
|
+
on push to `master` when `package.json`, `models/default/**`,
|
|
480
|
+
`python/tests/gold*.jsonl`, or `demo/**` change. One-time setup: add an
|
|
481
|
+
`HF_TOKEN` repo secret with a write-scoped Hugging Face token for the
|
|
482
|
+
`athrvk` namespace — without it the workflow prints a notice and skips.
|
|
483
|
+
See `python/README.md`'s "Publishing to Hugging Face" section for the
|
|
484
|
+
underlying `python -m sankhya.hf_push` CLI (including `--dry-run`).
|
package/dist/charset.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const MAX_LEN = 128;
|
|
2
2
|
export declare const WINDOW_OVERLAP = 16;
|
|
3
|
-
export declare const PAD_TAIL =
|
|
3
|
+
export declare const PAD_TAIL = 24;
|
|
4
4
|
/** Total (padded) inference length for a window/text of `realLen` real
|
|
5
5
|
* characters: realLen + at least PAD_TAIL pad chars, rounded up to a
|
|
6
6
|
* multiple of 8. */
|
package/dist/core.d.ts
CHANGED
|
@@ -15,6 +15,31 @@ export declare function evaluate(rawTokens: Tok[]): Result;
|
|
|
15
15
|
* sorted longest-first so `detectCurrency` tries the longest (most
|
|
16
16
|
* specific) marker before a shorter one that might be its prefix (e.g.
|
|
17
17
|
* "Rs." before "Rs", "रुपये" before a shorter overlapping marker). */
|
|
18
|
+
/** R3: true when a span's meaningful tokens are ONLY digits (with
|
|
19
|
+
* DOT/COMMA/SEP glue) -- no UNIT_/PFX_/CARD_ token at all. Such a span is
|
|
20
|
+
* dropped by the caller unless a currency marker is detected for it. */
|
|
21
|
+
export declare function isBareDigits(tokens: Tok[]): boolean;
|
|
22
|
+
/** R3 (narrowed): whether a bare-digits span (see isBareDigits) with NO
|
|
23
|
+
* detected currency should be dropped. Most bare numbers ARE amounts
|
|
24
|
+
* (rent, prices, quantities: "15000", "2,50,00,000", "125,000") and must
|
|
25
|
+
* be kept; only the two genuinely ambiguous shapes are dropped:
|
|
26
|
+
*
|
|
27
|
+
* (a) short (<=4 digits) AND ungrouped (no comma) -- route numbers,
|
|
28
|
+
* OTPs, years, house numbers: "1", "66", "4521", "2024", "302".
|
|
29
|
+
* (b) very long (>=10 digits) -- phone numbers: "9876543210".
|
|
30
|
+
*
|
|
31
|
+
* A grouping comma (Indian or Western) is itself a strong signal of a
|
|
32
|
+
* real amount, so it exempts an otherwise-short span from rule (a):
|
|
33
|
+
* "1,00,000" (6 digits, comma) is kept, not dropped. */
|
|
34
|
+
export declare function shouldDropBareDigits(tokens: Tok[]): boolean;
|
|
18
35
|
export declare function mergeLangPacks(...packs: LangPack[]): LangPack;
|
|
36
|
+
/** Scan up to 8 chars before/after [start,end) for a currency marker. The
|
|
37
|
+
* window has to be wider than the longest marker word (6 chars, e.g.
|
|
38
|
+
* "rupaye"/"rupees"): the span boundary sits right after the number, so
|
|
39
|
+
* the gap before the marker word starts (whitespace, and occasionally
|
|
40
|
+
* punctuation like ", ") eats into a same-sized window and truncates the
|
|
41
|
+
* word -- "1200 rupees" with a 6-char after-window is " rupee" (missing
|
|
42
|
+
* the final "s"), so "rupees" never matches with startsWith(). 8 leaves
|
|
43
|
+
* slack for a couple of separator chars ahead of the longest marker. */
|
|
19
44
|
export declare function detectCurrency(text: string, start: number, end: number, pack: LangPack): "INR" | null;
|
|
20
45
|
export {};
|
package/dist/decode.d.ts
CHANGED
|
@@ -12,4 +12,19 @@ export interface DecodedSpan {
|
|
|
12
12
|
tokens: Array<[number, string]>;
|
|
13
13
|
confidence: number | null;
|
|
14
14
|
}
|
|
15
|
+
/** [start, end) maximal letter/mark runs over the WHOLE text (not just one
|
|
16
|
+
* span) -- word integrity needs the true word boundaries, which can extend
|
|
17
|
+
* outside a span that was cut short mid-word. */
|
|
18
|
+
export declare function letterRuns(text: string): Array<[number, number]>;
|
|
19
|
+
/** R2: a word-class (UNIT_/PFX_/CARD_) token must cover its entire letter
|
|
20
|
+
* word. Checked per WHOLE letters-run rather than per token, so a run
|
|
21
|
+
* legitimately split into several back-to-back meaningful tokens (e.g.
|
|
22
|
+
* "dedhlakh" = PFX_DEDH|UNIT_LAKH, both length-4 sub-runs) is left alone; a
|
|
23
|
+
* run that is only PARTIALLY meaningful (some chars fall back to O, e.g.
|
|
24
|
+
* "km" tagged UNIT_.../O) has ALL its meaningful chars retagged O too -- a
|
|
25
|
+
* partial match without an explanation for the rest of the word is
|
|
26
|
+
* untrustworthy. A single-character symbol unit (k/K/l/L) is additionally
|
|
27
|
+
* only valid when the following character is not a letter, even when it
|
|
28
|
+
* fully (and only) covers its own run. */
|
|
29
|
+
export declare function repairWordIntegrity(text: string, s: number, e: number, ids: number[] | Int32Array, runs: Array<[number, number]>): number[];
|
|
15
30
|
export declare function decodeSpans(text: string, bioIds: number[] | Int32Array, clsIds: number[] | Int32Array, bioProbs?: Float32Array[] | number[][] | null): DecodedSpan[];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { Sankhya, ParseOptions, WeightsJson } from "./types.js";
|
|
2
|
-
export type { Sankhya, ParseOptions } from "./types.js";
|
|
1
|
+
import type { Sankhya, ParseOptions, WeightsJson, Inspection, ModelInfo } from "./types.js";
|
|
2
|
+
export type { Sankhya, ParseOptions, CharTag, Inspection, ModelInfo } from "./types.js";
|
|
3
3
|
export { isWebGPUAvailable, probeWebGPU } from "./infer-webgpu.js";
|
|
4
4
|
export { normalizeText } from "./charset.js";
|
|
5
|
+
export { CLASSES } from "./classes.js";
|
|
5
6
|
export interface CreateParserOptions {
|
|
6
7
|
weights?: WeightsJson;
|
|
7
8
|
backend?: "cpu" | "webgpu" | "auto";
|
|
@@ -31,6 +32,15 @@ export declare class Parser {
|
|
|
31
32
|
* actual text -- the padded tail's logits are only used to give the real
|
|
32
33
|
* tokens correct right-context during the conv stack, never decoded. */
|
|
33
34
|
private decodeForward;
|
|
35
|
+
/** Synchronous CPU inspection: raw argmax BIO/class tags for every
|
|
36
|
+
* character of the normalized text (before decode repair), plus the same
|
|
37
|
+
* spans `parse()` would return. Uses the same window/padding logic as
|
|
38
|
+
* parse(): for texts longer than MAX_LEN, each character is filled from
|
|
39
|
+
* the first window that covers it. */
|
|
40
|
+
inspect(text: string): Inspection;
|
|
41
|
+
/** Static info about the loaded model: architecture, parameter count and
|
|
42
|
+
* vocab/class sizes. */
|
|
43
|
+
modelInfo(): ModelInfo;
|
|
34
44
|
/** Batched parse. Uses WebGPU when requested/available and the batch is
|
|
35
45
|
* large enough to be worthwhile; falls back to CPU otherwise. */
|
|
36
46
|
parseBatch(texts: string[], opts?: ParseOptions): Promise<Sankhya[][]>;
|
|
@@ -42,4 +52,8 @@ export declare function parse(text: string, opts?: ParseOptions): Sankhya[];
|
|
|
42
52
|
* when `opts.backend === "auto"` and WebGPU is available and the batch is
|
|
43
53
|
* large (>=32); otherwise runs on CPU. Defaults to CPU. */
|
|
44
54
|
export declare function parseBatch(texts: string[], opts?: ParseOptions): Promise<Sankhya[][]>;
|
|
55
|
+
/** Inspect a single string on the default parser -- see Parser.inspect(). */
|
|
56
|
+
export declare function inspect(text: string): Inspection;
|
|
57
|
+
/** Info about the default parser's loaded model -- see Parser.modelInfo(). */
|
|
58
|
+
export declare function modelInfo(): ModelInfo;
|
|
45
59
|
export declare function createParser(opts?: CreateParserOptions): Parser;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
function pA(A){return A.quantized!==void 0}function LA(A){let e=atob(A),n=new Int8Array(e.length);for(let r=0;r<e.length;r++)n[r]=e.charCodeAt(r)<<24>>24;return n}function nA(A){let e=LA(A.data_b64),n=new Float32Array(e.length);for(let r=0;r<e.length;r++)n[r]=e[r]*A.scale;return{shape:A.shape,data:n}}function rA(A){return{shape:A.shape,data:Float32Array.from(A.data)}}function tA(A){let e=A.layers??3,n=A.dilation??2,r=["conv1","conv2","conv3",...e===4?["conv4"]:[]];if(pA(A)){let s={layers:e,dilation:n,charset:A.charset,classes:A.classes,embed:nA(A.embed),conv1:void 0,conv2:void 0,conv3:void 0,bio:void 0,cls:void 0};for(let o of[...r,"bio","cls"]){let a=A[o];s[o]={w:nA(a.w),b:Float32Array.from(a.b)}}return s}let f=A,t={layers:e,dilation:n,charset:f.charset,classes:f.classes,embed:rA(f.embed),conv1:void 0,conv2:void 0,conv3:void 0,bio:void 0,cls:void 0};for(let s of[...r,"bio","cls"]){let o=f[s];t[s]={w:rA(o.w),b:Float32Array.from(o.b.data)}}return t}function HA(A){return Math.ceil(A/8)*8}function F(A){return HA(A+16)}var M=F(128),MA=/[०-९]/g;function x(A){return A.normalize("NFC").replace(MA,e=>String(e.charCodeAt(0)-2406)).toLowerCase()}function sA(A){let e=new Map;for(let n=0;n<A.length;n++)e.set(A[n],n);return e}function T(A,e,n,r){let f=e.get("<unk>")??1,t=e.get("<pad>")??0,s=r??A.length,o=n?n.subarray(0,s):new Int32Array(s);for(let a=0;a<A.length;a++)o[a]=e.get(A[a])??f;for(let a=A.length;a<s;a++)o[a]=t;return o}function oA(A){if(A<=128)return[{offset:0,length:A}];let e=[],n=112,r=0;for(;r<A;){let f=Math.min(128,A-r);if(e.push({offset:r,length:f}),r+f>=A)break;r+=n}return e}var U=class{buffers;padded;bioBuf;clsBuf;constructor(e){let n=[e.conv1,e.conv2,e.conv3,...e.layers===4&&e.conv4?[e.conv4]:[]],r=Math.max(e.embed.shape[1],...n.map(t=>t.w.shape[0]));this.buffers=[new Float32Array(r*M),new Float32Array(r*M)];let f=8;this.padded=new Float32Array(r*(M+2*f)),this.bioBuf=new Float32Array(e.bio.w.shape[0]*M),this.clsBuf=new Float32Array(e.cls.w.shape[0]*M)}buf(e){return this.buffers[e%2]}paddedBuf(){return this.padded}};function O(A,e,n,r,f,t,s,o){let[a,u,c]=r.w.shape;if(u!==e)throw new Error(`channel mismatch: expected ${e}, got ${u}`);let v=r.w.data,B=r.b,g=n+2*f;for(let D=0;D<e;D++)o.fill(0,D*g,D*g+f),o.set(A.subarray(D*n,D*n+n),D*g+f),o.fill(0,D*g+f+n,D*g+g);for(let D=0;D<a;D++){let i=D*n,l=B[D],I=D*e*c;if(c===3){for(let P=0;P<n;P++)s[i+P]=l;for(let P=0;P<e;P++){let h=P*g,d=I+P*3,p=v[d],b=v[d+1],C=v[d+2];for(let w=0;w<n;w++){let Q=h+w;s[i+w]+=p*o[Q]+b*o[Q+t]+C*o[Q+2*t]}}}else if(c===5){for(let P=0;P<n;P++)s[i+P]=l;for(let P=0;P<e;P++){let h=P*g,d=I+P*5,p=v[d],b=v[d+1],C=v[d+2],w=v[d+3],Q=v[d+4];for(let H=0;H<n;H++){let L=h+H;s[i+H]+=p*o[L]+b*o[L+1]+C*o[L+2]+w*o[L+3]+Q*o[L+4]}}}else{for(let P=0;P<n;P++)s[i+P]=l;for(let P=0;P<e;P++){let h=P*g,d=I+P*c;for(let p=0;p<c;p++){let b=v[d+p],C=p*t,w=h+C;for(let Q=0;Q<n;Q++)s[i+Q]+=b*o[w+Q]}}}for(let P=0;P<n;P++){let h=s[i+P];s[i+P]=h>0?h:0}}return a}function fA(A,e,n,r,f){let[t,s]=r.w.shape;if(s!==e)throw new Error(`head channel mismatch: expected ${e}, got ${s}`);let o=r.w.data,a=r.b,u=e-e%4;for(let c=0;c<n;c++){let v=c*t;for(let B=0;B<t;B++){let g=a[B],D=B*e,i=0;for(;i<u;i+=4)g+=o[D+i]*A[i*n+c]+o[D+i+1]*A[(i+1)*n+c]+o[D+i+2]*A[(i+2)*n+c]+o[D+i+3]*A[(i+3)*n+c];for(;i<e;i++)g+=o[D+i]*A[i*n+c];f[v+B]=g}}return t}function S(A,e,n){let r=e.length,f=A.embed,t=f.shape[1],s=n.buf(0);for(let g=0;g<r;g++){let i=e[g]*t;for(let l=0;l<t;l++)s[l*r+g]=f.data[i+l]}let o=t,a=n.paddedBuf(),u=n.buf(1);o=O(s,o,r,A.conv1,1,1,u,a),s=u,u=n.buf(2),o=O(s,o,r,A.conv2,2,1,u,a),s=u;let c=A.dilation,v=Math.floor(c*2/2);if(u=n.buf(3),o=O(s,o,r,A.conv3,v,c,u,a),s=u,A.layers===4&&A.conv4){let D=Math.floor(4);u=n.buf(4),o=O(s,o,r,A.conv4,D,4,u,a),s=u}fA(s,o,r,A.bio,n.bioBuf);let B=fA(s,o,r,A.cls,n.clsBuf);return{bioLogits:n.bioBuf,clsLogits:n.clsBuf,length:r,nCls:B}}function aA(A,e,n,r){let f=-1/0;for(let s=0;s<n;s++)f=Math.max(f,A[e+s]);let t=0;for(let s=0;s<n;s++){let o=Math.exp(A[e+s]-f);r[s]=o,t+=o}for(let s=0;s<n;s++)r[s]/=t;return r}function J(A,e,n){let r=0,f=-1/0;for(let t=0;t<n;t++){let s=A[e+t];s>f&&(f=s,r=t)}return r}var RA=["PFX_PAAV","PFX_AADHA","PFX_PAUNE","PFX_SAVA","PFX_DEDH","PFX_DHAI","PFX_SAADHE"],yA=Array.from({length:99},(A,e)=>`CARD_${e+1}`),FA=["UNIT_SAU","UNIT_HAZAAR","UNIT_LAKH","UNIT_MILLION","UNIT_CRORE","UNIT_BILLION","UNIT_ARAB","UNIT_KHARAB"],mA=["O","SEP","RANGE","DIGITS","DOT","COMMA"],R=["O",...mA.filter(A=>A!=="O"),...RA,...yA,...FA],y=Object.fromEntries(R.map((A,e)=>[A,e])),uA={UNIT_SAU:100,UNIT_HAZAAR:1e3,UNIT_LAKH:1e5,UNIT_MILLION:1e6,UNIT_CRORE:1e7,UNIT_BILLION:1e9,UNIT_ARAB:1e9,UNIT_KHARAB:1e11},K={UNIT_SAU:"sau",UNIT_HAZAAR:"hazaar",UNIT_LAKH:"lakh",UNIT_MILLION:"million",UNIT_CRORE:"crore",UNIT_BILLION:"billion",UNIT_ARAB:"arab",UNIT_KHARAB:"kharab"},W={PFX_PAAV:{standalone:.25,op:null},PFX_AADHA:{standalone:.5,op:null},PFX_PAUNE:{standalone:.75,op:"sub25",min_n:2},PFX_SAVA:{standalone:1.25,op:"add25",min_n:2},PFX_DEDH:{standalone:1.5,op:null},PFX_DHAI:{standalone:2.5,op:null},PFX_SAADHE:{standalone:.5,op:"add5",min_n:3}};function cA(A){return A in W}function gA(A){return A.startsWith("CARD_")}function BA(A){return A in uA}function iA(A){return parseInt(A.split("_",2)[1],10)}function G(A){return uA[A]}var PA=new Set(["SEP","RANGE","DOT","COMMA"]),TA=["PFX_","CARD_","UNIT_"],OA=["PFX_","CARD_","UNIT_"];function UA(A){return TA.some(e=>A.startsWith(e))||A==="DIGITS"}function GA(A){return OA.some(e=>A.startsWith(e))}var kA=y.O,k=y.SEP,V=y.RANGE,zA=y.DIGITS,NA=y.DOT,XA=y.COMMA,_A=/\p{L}|\p{M}/u;function vA(A){return _A.test(A)?"letter":/[0-9]/.test(A)?"digit":/\s/.test(A)?"space":"punct"}function YA(A){let e=[],n=0,r=A.length;for(;n<r;){let f=vA(A[n]),t=n+1;for(;t<r&&vA(A[t])===f;)t++;e.push({type:f,start:n,end:t}),n=t}return e}function jA(A,e,n){let r=new Map;for(let u=e;u<n;u++){let c=A[u];GA(R[c])&&r.set(c,(r.get(c)??0)+1)}if(r.size===0)return kA;let f=-1;for(let u of r.values())u>f&&(f=u);let t=[...r.entries()].filter(([,u])=>u===f).map(([u])=>u);if(t.length===1)return t[0];let s=-1,o=1/0,a=t[0];for(let u of t){let c=0,v=0,B=1/0;for(let g=e;g<n;g++)A[g]===u?(B===1/0&&(B=g),c++,c>v&&(v=c)):c=0;(v>s||v===s&&B<o)&&(s=v,o=B,a=u)}return a}function SA(A,e,n){let r=[],f=e;for(;f<n;){let o=f+1;for(;o<n&&A[o]===A[f];)o++;r.push({start:f,end:o,cls:A[f]}),f=o}let t=jA(A,e,n),s=[];for(let o=0;o<r.length;o++){let a=r[o];if(a.end-a.start>=3){s.push([a.start,a.end,a.cls]);continue}let c=o>0?r[o-1]:null,v=o<r.length-1?r[o+1]:null,B=c!==null&&c.end-c.start>=3,g=v!==null&&v.end-v.start>=3,D;if(B&&g){let i=c.end-c.start;D=v.end-v.start>i?v.cls:c.cls}else B?D=c.cls:g?D=v.cls:D=t;s.push([a.start,a.end,D])}return s}function JA(A,e){let n=A.length,r=new Array(n),f=YA(A);for(let t=0;t<f.length;t++){let s=f[t],{type:o,start:a,end:u}=s;if(o==="digit"){for(let g=a;g<u;g++)r[g]=zA;continue}if(o==="space"){let g=!1;for(let i=a;i<u;i++)if(e[i]===V){g=!0;break}let D=g?V:k;for(let i=a;i<u;i++)r[i]=D;continue}if(o==="letter"){for(let[g,D,i]of SA(e,a,u))for(let l=g;l<D;l++)r[l]=i;continue}let c=t>0?f[t-1].type:null,v=t<f.length-1?f[t+1].type:null,B=k;if(u-a===1){let g=A[a];(g==="."||g===",")&&c==="digit"&&v==="digit"?B=g==="."?NA:XA:(g==="-"||g==="\u2013"||g==="/")&&c==="digit"&&v==="digit"?B=V:B=k}for(let g=a;g<u;g++)r[g]=B}return r}function KA(A,e){let n=Array.from({length:e},(r,f)=>A[f]);for(let r=1;r<e-1;r++)A[r]===0&&(A[r-1]===1||A[r-1]===2)&&A[r+1]===2&&(n[r]=2);return n}function DA(A){return A!==void 0&&A>="0"&&A<="9"}function WA(A,e,n){if(n<=e||!DA(A[n-1]))return n;let r=n;for(;r<A.length&&DA(A[r]);)r++;return r}function CA(A,e,n,r){let f=A.length,t=KA(e,f),s=[],o=null;for(let u=0;u<f;u++){let c=t[u];c===1?(o!==null&&s.push([o,u]),o=u):c===2||o!==null&&(s.push([o,u]),o=null)}o!==null&&s.push([o,f]);for(let u=0;u<s.length;u++)s[u]=[s[u][0],WA(A,s[u][0],s[u][1])];let a=[];for(let[u,c]of s){let v=A.slice(u,c),B=Array.from({length:c-u},(b,C)=>n[u+C]),g=JA(v,B),D=u,i=[];for(let b=u+1;b<=c;b++)(b===c||g[b-u]!==g[D-u])&&(i.push([g[D-u],D,b]),D=b);let l=0,I=i.length;for(;l<I&&PA.has(R[i[l][0]]);)l++;for(;I>l&&PA.has(R[i[I-1][0]]);)I--;let P=i.slice(l,I);if(P.length===0)continue;let h=P[0][1],d=P[P.length-1][2];if(!P.some(([b])=>UA(R[b])))continue;let p=null;if(r){let b=[];for(let C=h;C<d;C++)b.push(Math.max(...r[C]));if(p=b.length?b.reduce((C,w)=>C+w,0)/b.length:0,p<.5)continue}a.push({start:h,end:d,text:A.slice(h,d),tokens:P.map(([b,C,w])=>[b,A.slice(C,w)]),confidence:p})}return a}function VA(A){let e=[],n="",r=!1,f=()=>{if(r){let t=n.replace(/,/g,""),s=parseFloat(t);e.push(["NUM",Number.isNaN(s)?0:s])}n="",r=!1};for(let[t,s]of A)t!=="SEP"&&(t==="DIGITS"||t==="DOT"||t==="COMMA"?(n+=s,r=!0):(f(),e.push([t,s])));return f(),e}function qA(A,e){if(e!==null){let n=W[e];if(n===void 0)return A!==null?A:1;if(A!==null&&n.op){if(n.op==="sub25")return A-.25;if(n.op==="add25")return A+.25;if(n.op==="add5")return A+.5}return n.standalone}return A!==null?A:1}function ZA(A){let e=VA(A),n=0,r=null,f=null,t=null,s=null;function o(a){let u=qA(t,s);if(a===null)n+=u*1;else{let c=G(a);r!==null&&c>r?n=n*c:n=n+u*c,r=c,(f===null||c>G(f))&&(f=a)}t=null,s=null}for(let[a,u]of e)if(a==="NUM")t!==null&&o(null),t=u;else if(gA(a)){t!==null&&o(null);try{t=iA(a)}catch{}}else if(cA(a))s!==null&&o(null),s=a;else if(BA(a))o(a);else continue;return(t!==null||s!==null)&&o(null),[n,f]}function z(A){let e=Math.round(A),n=Math.max(1e-6,Math.abs(A)*1e-9);return Math.abs(A-e)<n?e:Math.round(A*1e6)/1e6}function $A(A){let e=[],n=0;for(;n<A.length;){let[r,f]=A[n];if(r.startsWith("PFX_")){let t=f,s=n+1;for(;;){let o=s;if(o<A.length&&A[o][0]==="SEP"&&o++,o<A.length&&A[o][0]===r){for(let a=s;a<=o;a++)t+=A[a][1];s=o+1;continue}break}e.push([r,t]),n=s}else e.push(A[n]),n++}return e}function wA(A){try{let e=A.map(B=>B[0]),n=$A(A),r=[[]];for(let[B,g]of n){if(B==="RANGE"){r.length<2&&r.push([]);continue}r[r.length-1].push([B,g])}let f=r.filter(B=>B.length>0).map(B=>ZA(B));if(f.length===0)return{value:0,range:null,unit:null,classes:e,currency:null};if(f.length===1){let[B,g]=f[0];return{value:z(B),range:null,unit:g?K[g]??null:null,classes:e,currency:null}}let[t,s]=f[0],[o,a]=f[1],u;s===null&&a!==null?(t=t*G(a),u=a):u=s!==null?s:a;let[c,v]=t<=o?[t,o]:[o,t];return{value:z(c),range:[z(c),z(v)],unit:u?K[u]??null:null,classes:e,currency:null}}catch{return{value:0,range:null,unit:null,classes:A.map(e=>e[0]),currency:null}}}function lA(...A){let e=(r,f)=>f.length-r.length,n=r=>[...new Set(r.flat())].sort(e);return{currency_markers_before:n(A.map(r=>r.currency_markers_before??[])),currency_words_after:n(A.map(r=>r.currency_words_after??[]))}}function QA(A,e,n,r){let f=A.slice(Math.max(0,e-4),e),t=A.slice(n,n+6),o=f.replace(/\s+$/,"").toLowerCase(),a=[...r.currency_markers_before??[]].sort((B,g)=>g.length-B.length);for(let B of a){let g=B.replace(/\.+$/,"").toLowerCase();if(o.endsWith(B.toLowerCase())||o.endsWith(g))return"INR"}let c=t.replace(/^\s+/,"").toLowerCase(),v=[...r.currency_words_after??[]].sort((B,g)=>g.length-B.length);for(let B of v){let g=B.toLowerCase();if(c.startsWith(g))return"INR"}return null}var bA={currency_markers_before:["\u20B9","Rs","Rs.","rs","INR","Re"],currency_words_after:["rupaye","rupay","rupees","rupiya","rupya","/-"]};var EA={currency_markers_before:["\u20B9","\u0930\u0941","\u0930\u0941.","Rs","Rs.","INR"],currency_words_after:["\u0930\u0941\u092A\u092F\u0947","\u0930\u0941\u092A\u090F","\u0930\u0942\u092A\u092F\u0947","\u0930\u0941\u092A\u092F\u093E","/-"]};var Ae=`
|
|
1
|
+
function GA(A){return A.version===2&&Array.isArray(A.conv)}function TA(A){return A.quantized!==void 0}function kA(A){let e=atob(A),B=new Int8Array(e.length);for(let n=0;n<e.length;n++)B[n]=e.charCodeAt(n)<<24>>24;return B}function G(A){let e=kA(A.data_b64),B=new Float32Array(e.length);for(let n=0;n<e.length;n++)B[n]=e[n]*A.scale;return{shape:A.shape,data:B}}function T(A){return{shape:A.shape,data:Float32Array.from(A.data)}}function PA(A,e){return A*(e-1)/2}function X(A){return{w:T(A.w),b:Float32Array.from(A.b.data)}}function N(A){return{w:G(A.w),b:Float32Array.from(A.b)}}function oA(A){let e=TA(A);if(GA(A)){let f=A.conv.map(s=>{let g=PA(s.dilation,s.k);if(e){let o=s;return{k:s.k,dilation:s.dilation,residual:s.residual,padding:g,w:G(o.w),b:Float32Array.from(o.b)}}let P=s;return{k:s.k,dilation:s.dilation,residual:s.residual,padding:g,w:T(P.w),b:Float32Array.from(P.b.data)}});return{version:2,charset:A.charset,classes:A.classes,embed:e?G(A.embed):T(A.embed),conv:f,bio:e?N(A.bio):X(A.bio),cls:e?N(A.cls):X(A.cls)}}let B=A.layers??3,n=A.dilation??2,t=[{name:"conv1",k:3,dilation:1},{name:"conv2",k:5,dilation:1},{name:"conv3",k:3,dilation:n}];B===4&&t.push({name:"conv4",k:3,dilation:4});let r=t.map(f=>{let s=PA(f.dilation,f.k);if(e){let w=A[f.name];if(!w)throw new Error(`missing ${f.name} in weights JSON`);return{k:f.k,dilation:f.dilation,residual:!1,padding:s,w:G(w.w),b:Float32Array.from(w.b)}}let P=A[f.name];if(!P)throw new Error(`missing ${f.name} in weights JSON`);return{k:f.k,dilation:f.dilation,residual:!1,padding:s,w:T(P.w),b:Float32Array.from(P.b.data)}});return{version:A.version??1,charset:A.charset,classes:A.classes,embed:e?G(A.embed):T(A.embed),conv:r,bio:e?N(A.bio):X(A.bio),cls:e?N(A.cls):X(A.cls)}}function zA(A){return Math.ceil(A/8)*8}function x(A){return zA(A+24)}var R=x(128),pA=/[०-९]/g;function k(A){return A.normalize("NFC").replace(pA,e=>String(e.charCodeAt(0)-2406)).toLowerCase()}function wA(A){let e=new Map;for(let B=0;B<A.length;B++)e.set(A[B],B);return e}function z(A,e,B,n){let t=e.get("<unk>")??1,r=e.get("<pad>")??0,f=n??A.length,s=B?B.subarray(0,f):new Int32Array(f);for(let g=0;g<A.length;g++)s[g]=e.get(A[g])??t;for(let g=A.length;g<f;g++)s[g]=r;return s}function eA(A){if(A<=128)return[{offset:0,length:A}];let e=[],B=112,n=0;for(;n<A;){let t=Math.min(128,A-n);if(e.push({offset:n,length:t}),n+t>=A)break;n+=B}return e}var j=class{buffers;padded;bioBuf;clsBuf;constructor(e){let B=e.conv,n=Math.max(e.embed.shape[1],...B.map(r=>r.w.shape[0]));this.buffers=[new Float32Array(n*R),new Float32Array(n*R)];let t=B.length?Math.max(...B.map(r=>r.padding)):0;this.padded=new Float32Array(n*(R+2*t)),this.bioBuf=new Float32Array(e.bio.w.shape[0]*R),this.clsBuf=new Float32Array(e.cls.w.shape[0]*R)}buf(e){return this.buffers[e%2]}paddedBuf(){return this.padded}};function yA(A,e,B,n,t,r){let[f,s,g]=n.w.shape;if(s!==e)throw new Error(`channel mismatch: expected ${e}, got ${s}`);let P=n.w.data,o=n.b,w=n.padding,D=n.dilation,C=B+2*w;for(let u=0;u<e;u++)r.fill(0,u*C,u*C+w),r.set(A.subarray(u*B,u*B+B),u*C+w),r.fill(0,u*C+w+B,u*C+C);for(let u=0;u<f;u++){let v=u*B,I=o[u],l=u*e*g;if(g===3){for(let Q=0;Q<B;Q++)t[v+Q]=I;for(let Q=0;Q<e;Q++){let b=Q*C,i=l+Q*3,M=P[i],L=P[i+1],a=P[i+2];for(let c=0;c<B;c++){let E=b+c;t[v+c]+=M*r[E]+L*r[E+D]+a*r[E+2*D]}}}else if(g===5){for(let Q=0;Q<B;Q++)t[v+Q]=I;for(let Q=0;Q<e;Q++){let b=Q*C,i=l+Q*5,M=P[i],L=P[i+1],a=P[i+2],c=P[i+3],E=P[i+4];for(let H=0;H<B;H++){let d=b+H;t[v+H]+=M*r[d]+L*r[d+1]+a*r[d+2]+c*r[d+3]+E*r[d+4]}}}else{for(let Q=0;Q<B;Q++)t[v+Q]=I;for(let Q=0;Q<e;Q++){let b=Q*C,i=l+Q*g;for(let M=0;M<g;M++){let L=P[i+M],a=M*D,c=b+a;for(let E=0;E<B;E++)t[v+E]+=L*r[c+E]}}}if(n.residual)for(let Q=0;Q<B;Q++){let b=t[v+Q];t[v+Q]=(b>0?b:0)+A[v+Q]}else for(let Q=0;Q<B;Q++){let b=t[v+Q];t[v+Q]=b>0?b:0}}return f}function DA(A,e,B,n,t){let[r,f]=n.w.shape;if(f!==e)throw new Error(`head channel mismatch: expected ${e}, got ${f}`);let s=n.w.data,g=n.b,P=e-e%4;for(let o=0;o<B;o++){let w=o*r;for(let D=0;D<r;D++){let C=g[D],u=D*e,v=0;for(;v<P;v+=4)C+=s[u+v]*A[v*B+o]+s[u+v+1]*A[(v+1)*B+o]+s[u+v+2]*A[(v+2)*B+o]+s[u+v+3]*A[(v+3)*B+o];for(;v<e;v++)C+=s[u+v]*A[v*B+o];t[w+D]=C}}return r}function S(A,e,B){let n=e.length,t=A.embed,r=t.shape[1],f=B.buf(0);for(let w=0;w<n;w++){let C=e[w]*r;for(let u=0;u<r;u++)f[u*n+w]=t.data[C+u]}let s=r,g=B.paddedBuf(),P=1;for(let w of A.conv){let D=B.buf(P);s=yA(f,s,n,w,D,g),f=D,P++}DA(f,s,n,A.bio,B.bioBuf);let o=DA(f,s,n,A.cls,B.clsBuf);return{bioLogits:B.bioBuf,clsLogits:B.clsBuf,length:n,nCls:o}}function BA(A,e,B,n){let t=-1/0;for(let f=0;f<B;f++)t=Math.max(t,A[e+f]);let r=0;for(let f=0;f<B;f++){let s=Math.exp(A[e+f]-t);n[f]=s,r+=s}for(let f=0;f<B;f++)n[f]/=r;return n}function p(A,e,B){let n=0,t=-1/0;for(let r=0;r<B;r++){let f=A[e+r];f>t&&(t=f,n=r)}return n}var mA=["PFX_PAAV","PFX_AADHA","PFX_PAUNE","PFX_SAVA","PFX_DEDH","PFX_DHAI","PFX_SAADHE"],YA=Array.from({length:99},(A,e)=>`CARD_${e+1}`),XA=["UNIT_SAU","UNIT_HAZAAR","UNIT_LAKH","UNIT_MILLION","UNIT_CRORE","UNIT_BILLION","UNIT_ARAB","UNIT_KHARAB"],NA=["O","SEP","RANGE","DIGITS","DOT","COMMA"],F=["O",...NA.filter(A=>A!=="O"),...mA,...YA,...XA],O=Object.fromEntries(F.map((A,e)=>[A,e])),CA={UNIT_SAU:100,UNIT_HAZAAR:1e3,UNIT_LAKH:1e5,UNIT_MILLION:1e6,UNIT_CRORE:1e7,UNIT_BILLION:1e9,UNIT_ARAB:1e9,UNIT_KHARAB:1e11},J={UNIT_SAU:"sau",UNIT_HAZAAR:"hazaar",UNIT_LAKH:"lakh",UNIT_MILLION:"million",UNIT_CRORE:"crore",UNIT_BILLION:"billion",UNIT_ARAB:"arab",UNIT_KHARAB:"kharab"},nA={PFX_PAAV:{standalone:.25,op:null},PFX_AADHA:{standalone:.5,op:null},PFX_PAUNE:{standalone:.75,op:"sub25",min_n:2},PFX_SAVA:{standalone:1.25,op:"add25",min_n:2},PFX_DEDH:{standalone:1.5,op:null},PFX_DHAI:{standalone:2.5,op:null},PFX_SAADHE:{standalone:.5,op:"add5",min_n:3}};function QA(A){return A in nA}function vA(A){return A.startsWith("CARD_")}function uA(A){return A in CA}function cA(A){return parseInt(A.split("_",2)[1],10)}function K(A){return CA[A]}var SA=new Set(["SEP","RANGE","DOT","COMMA"]),EA=new Set([...SA,"O"]),tA=["PFX_","CARD_","UNIT_"],JA=["PFX_","CARD_","UNIT_"],KA=new Set(["-","\u2013","\u2014","/"]),_A=new Set(["k","K","l","L"]),aA=/['’]([A-Za-zऀ-ॿ]{1,2})(?![A-Za-zऀ-ॿ])/g;function WA(A){return tA.some(e=>A.startsWith(e))||A==="DIGITS"}function VA(A){return JA.some(e=>A.startsWith(e))}var W=O.O,_=O.SEP,rA=O.RANGE,qA=O.DIGITS,ZA=O.DOT,$A=O.COMMA,Ae=/\p{L}|\p{M}/u;function y(A){return Ae.test(A)?"letter":/[0-9]/.test(A)?"digit":/\s/.test(A)?"space":"punct"}function ee(A){let e=[],B=0,n=A.length;for(;B<n;){let t=y(A[B]),r=B+1;for(;r<n&&y(A[r])===t;)r++;e.push({type:t,start:B,end:r}),B=r}return e}function Be(A,e,B){let n=new Map;for(let P=e;P<B;P++){let o=A[P];VA(F[o])&&n.set(o,(n.get(o)??0)+1)}if(n.size===0)return W;let t=-1;for(let P of n.values())P>t&&(t=P);let r=[...n.entries()].filter(([,P])=>P===t).map(([P])=>P);if(r.length===1)return r[0];let f=-1,s=1/0,g=r[0];for(let P of r){let o=0,w=0,D=1/0;for(let C=e;C<B;C++)A[C]===P?(D===1/0&&(D=C),o++,o>w&&(w=o)):o=0;(w>f||w===f&&D<s)&&(f=w,s=D,g=P)}return g}function hA(A,e,B){let n=[],t=e;for(;t<B;){let s=t+1;for(;s<B&&A[s]===A[t];)s++;n.push({start:t,end:s,cls:A[t]}),t=s}let r=Be(A,e,B),f=[];for(let s=0;s<n.length;s++){let g=n[s];if(g.end-g.start>=3){f.push([g.start,g.end,g.cls]);continue}let o=s>0?n[s-1]:null,w=s<n.length-1?n[s+1]:null,D=o!==null&&o.end-o.start>=3,C=w!==null&&w.end-w.start>=3,u;if(D&&C){let v=o.end-o.start;u=w.end-w.start>v?w.cls:o.cls}else D?u=o.cls:C?u=w.cls:u=r;f.push([g.start,g.end,u])}return f}function ne(A){return tA.some(e=>A.startsWith(e))||A==="DIGITS"}function iA(A,e,B,n){if(A==="digit")return"DIGITS";if(A==="letter"){let t=hA(n,e,B),r=new Map;for(let[g,P,o]of t)r.set(o,(r.get(o)??0)+(P-g));let f=-1,s=-1;for(let[g,P]of r)P>s&&(s=P,f=g);return f>=0?F[f]:null}return null}function IA(A,e,B){let n=e+B;if(n<0||n>=A.length||A[n].type==="space"&&(n+=B,n<0||n>=A.length))return null;let t=A[n];return t.type==="digit"||t.type==="letter"?t:null}function re(A,e,B){let n=IA(A,e,-1),t=IA(A,e,1);if(!n||!t)return!1;let r=iA(n.type,n.start,n.end,B),f=iA(t.type,t.start,t.end,B);return!r||!f||!ne(r)?!1:f==="DIGITS"||f.startsWith("CARD_")||f.startsWith("PFX_")}function te(A,e){let B=A.length,n=new Array(B),t=ee(A);for(let r=0;r<t.length;r++){let f=t[r],{type:s,start:g,end:P}=f;if(s==="digit"){for(let C=g;C<P;C++)n[C]=qA;continue}if(s==="space"){let C=!1;for(let v=g;v<P;v++)if(e[v]===rA){C=!0;break}let u=C?rA:_;for(let v=g;v<P;v++)n[v]=u;continue}if(s==="letter"){for(let[C,u,v]of hA(e,g,P))for(let I=C;I<u;I++)n[I]=v;continue}let o=r>0?t[r-1].type:null,w=r<t.length-1?t[r+1].type:null,D=_;if(P-g===1){let C=A[g];(C==="."||C===",")&&o==="digit"&&w==="digit"?D=C==="."?ZA:$A:KA.has(C)&&re(t,r,e)?D=rA:D=_}for(let C=g;C<P;C++)n[C]=D}return n}function fe(A,e){let B=Array.from({length:e},(n,t)=>A[t]);for(let n=1;n<e-1;n++)A[n]===0&&(A[n-1]===1||A[n-1]===2)&&A[n+1]===2&&(B[n]=2);return B}function lA(A){return A!==void 0&&A>="0"&&A<="9"}function se(A,e,B){if(B<=e||!lA(A[B-1]))return B;let n=B;for(;n<A.length&&lA(A[n]);)n++;return n}function ge(A){let e=[],B=0,n=A.length;for(;B<n;)if(y(A[B])==="letter"){let t=B+1;for(;t<n&&y(A[t])==="letter";)t++;e.push([B,t]),B=t}else B++;return e}function bA(A){return tA.some(e=>A.startsWith(e))&&A!=="DIGITS"}function Pe(A,e,B,n,t){let r=Array.from({length:n.length},(f,s)=>n[s]);for(let[f,s]of t){if(s<=e||f>=B)continue;let g=Math.max(f,e),P=Math.min(s,B),o=f>=e&&s<=B;if(o){for(let w=f;w<s;w++)if(!bA(F[r[w]])){o=!1;break}}if(o){s-f===1&&F[r[f]].startsWith("UNIT_")&&_A.has(A[f])&&s<A.length&&y(A[s])==="letter"&&(r[f]=W);continue}for(let w=g;w<P;w++)bA(F[r[w]])&&(r[w]=W)}return r}function oe(A,e,B,n){let t=Array.from({length:n.length},(s,g)=>n[g]),r=A.slice(e,B);aA.lastIndex=0;let f;for(;f=aA.exec(r);)for(let s=e+f.index;s<e+f.index+f[0].length;s++)t[s]=W;return t}function HA(A,e,B,n){let t=A.length,r=fe(e,t),f=[],s=null;for(let w=0;w<t;w++){let D=r[w];D===1?(s!==null&&f.push([s,w]),s=w):D===2||s!==null&&(f.push([s,w]),s=null)}s!==null&&f.push([s,t]);for(let w=0;w<f.length;w++)f[w]=[f[w][0],se(A,f[w][0],f[w][1])];let g=ge(A),P=Array.from({length:t},(w,D)=>B[D]),o=[];for(let[w,D]of f){let C=A.slice(w,D),u=Array.from({length:D-w},(c,E)=>P[w+E]),v=te(C,u);for(let c=w;c<D;c++)P[c]=v[c-w];P=Pe(A,w,D,P,g),P=oe(A,w,D,P);let I=w,l=[];for(let c=w+1;c<=D;c++)(c===D||P[c]!==P[I])&&(l.push([P[I],I,c]),I=c);let Q=0,b=l.length;for(;Q<b&&EA.has(F[l[Q][0]]);)Q++;for(;b>Q&&EA.has(F[l[b-1][0]]);)b--;let i=l.slice(Q,b);if(i.length===0)continue;let M=i[0][1],L=i[i.length-1][2];if(!i.some(([c])=>WA(F[c])))continue;let a=null;if(n){let c=[];for(let E=M;E<L;E++)c.push(Math.max(...n[E]));if(a=c.length?c.reduce((E,H)=>E+H,0)/c.length:0,a<.5)continue}o.push({start:M,end:L,text:A.slice(M,L),tokens:i.map(([c,E,H])=>[c,A.slice(E,H)]),confidence:a})}return o}function we(A){let e=[],B="",n=!1,t=()=>{if(n){let r=B.replace(/,/g,""),f=parseFloat(r);e.push(["NUM",Number.isNaN(f)?0:f])}B="",n=!1};for(let[r,f]of A)r!=="SEP"&&(r==="DIGITS"||r==="DOT"||r==="COMMA"?(B+=f,n=!0):(t(),e.push([r,f])));return t(),e}function De(A,e){if(e!==null){let B=nA[e];if(B===void 0)return A!==null?A:1;if(A!==null&&B.op){if(B.op==="sub25")return A-.25;if(B.op==="add25")return A+.25;if(B.op==="add5")return A+.5}return B.standalone}return A!==null?A:1}function Ce(A){let e=we(A),B=0,n=null,t=null,r=null,f=null;function s(g){let P=De(r,f);if(g===null)B+=P*1;else{let o=K(g);n!==null&&o>n?B=B*o:B=B+P*o,n=o,(t===null||o>K(t))&&(t=g)}r=null,f=null}for(let[g,P]of e)if(g==="NUM")r!==null&&s(null),r=P;else if(vA(g)){r!==null&&s(null);try{r=cA(g)}catch{}}else if(QA(g))f!==null&&s(null),f=g;else if(uA(g))s(g);else continue;return(r!==null||f!==null)&&s(null),[B,t]}function m(A){let e=Math.round(A),B=Math.max(1e-6,Math.abs(A)*1e-9);return Math.abs(A-e)<B?e:Math.round(A*1e6)/1e6}function Qe(A){let e=[],B=0;for(;B<A.length;){let[n,t]=A[B];if(n.startsWith("PFX_")){let r=t,f=B+1;for(;;){let s=f;if(s<A.length&&A[s][0]==="SEP"&&s++,s<A.length&&A[s][0]===n){for(let g=f;g<=s;g++)r+=A[g][1];f=s+1;continue}break}e.push([n,r]),B=f}else e.push(A[B]),B++}return e}function MA(A){try{let e=A.map(D=>D[0]),B=Qe(A),n=[[]];for(let[D,C]of B){if(D==="RANGE"){n.length<2&&n.push([]);continue}n[n.length-1].push([D,C])}let t=n.filter(D=>D.length>0).map(D=>Ce(D));if(t.length===0)return{value:0,range:null,unit:null,classes:e,currency:null};if(t.length===1){let[D,C]=t[0];return{value:m(D),range:null,unit:C?J[C]??null:null,classes:e,currency:null}}let[r,f]=t[0],[s,g]=t[1];if(f!==null&&g!==null&&r>s)return{value:m(r+s),range:null,unit:J[f]??null,classes:e,currency:null};let P;f===null&&g!==null?(r=r*K(g),P=g):P=f!==null?f:g;let[o,w]=r<=s?[r,s]:[s,r];return{value:m(o),range:[m(o),m(w)],unit:P?J[P]??null:null,classes:e,currency:null}}catch{return{value:0,range:null,unit:null,classes:A.map(e=>e[0]),currency:null}}}function ve(A){let e=!1;for(let[B]of A)if(B==="DIGITS")e=!0;else if(B.startsWith("UNIT_")||B.startsWith("PFX_")||B.startsWith("CARD_"))return!1;return e}function dA(A){if(!ve(A))return!1;let e=0,B=!1;for(let[n,t]of A)n==="DIGITS"?e+=t.length:n==="COMMA"&&(B=!0);return e<=4&&!B||e>=10}function FA(...A){let e=(n,t)=>t.length-n.length,B=n=>[...new Set(n.flat())].sort(e);return{currency_markers_before:B(A.map(n=>n.currency_markers_before??[])),currency_words_after:B(A.map(n=>n.currency_words_after??[]))}}function LA(A,e,B,n){let t=A.slice(Math.max(0,e-8),e),r=A.slice(B,B+8),s=t.replace(/\s+$/,"").toLowerCase(),g=[...n.currency_markers_before??[]].sort((D,C)=>C.length-D.length);for(let D of g){let C=D.replace(/\.+$/,"").toLowerCase();if(s.endsWith(D.toLowerCase())||s.endsWith(C))return"INR"}let o=r.replace(/^\s+/,"").toLowerCase(),w=[...n.currency_words_after??[]].sort((D,C)=>C.length-D.length);for(let D of w){let C=D.toLowerCase();if(o.startsWith(C))return"INR"}return null}var RA={currency_markers_before:["\u20B9","Rs","Rs.","rs","INR","Re"],currency_words_after:["rupaye","rupay","rupees","rupiya","rupya","/-"]};var OA={currency_markers_before:["\u20B9","\u0930\u0941","\u0930\u0941.","Rs","Rs.","INR"],currency_words_after:["\u0930\u0941\u092A\u092F\u0947","\u0930\u0941\u092A\u090F","\u0930\u0942\u092A\u092F\u0947","\u0930\u0941\u092A\u092F\u093E","/-"]};var ue=`
|
|
2
2
|
struct Params { batch: u32, length: u32, embedDim: u32, vocab: u32, stride: u32 };
|
|
3
3
|
@group(0) @binding(0) var<uniform> p: Params;
|
|
4
4
|
@group(0) @binding(1) var<storage, read> charIds: array<i32>;
|
|
@@ -17,8 +17,8 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
17
17
|
xOut[(b * p.embedDim + c) * p.length + t] = embed[cid * p.embedDim + c];
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
`,
|
|
21
|
-
struct Params { batch: u32, length: u32, cIn: u32, cOut: u32, k: u32, padding: u32, dilation: u32, relu: u32, stride: u32 };
|
|
20
|
+
`,ce=`
|
|
21
|
+
struct Params { batch: u32, length: u32, cIn: u32, cOut: u32, k: u32, padding: u32, dilation: u32, relu: u32, residual: u32, stride: u32 };
|
|
22
22
|
@group(0) @binding(0) var<uniform> p: Params;
|
|
23
23
|
@group(0) @binding(1) var<storage, read> x: array<f32>; // (batch, cIn, L)
|
|
24
24
|
@group(0) @binding(2) var<storage, read> w: array<f32>; // (cOut, cIn, k)
|
|
@@ -47,9 +47,12 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
if (p.relu != 0u && acc < 0.0) { acc = 0.0; }
|
|
50
|
+
if (p.residual != 0u) {
|
|
51
|
+
acc = acc + x[(b * p.cIn + oc) * p.length + t];
|
|
52
|
+
}
|
|
50
53
|
out[(b * p.cOut + oc) * p.length + t] = acc;
|
|
51
54
|
}
|
|
52
|
-
`,
|
|
55
|
+
`,Ee=`
|
|
53
56
|
struct Params { batch: u32, length: u32, cIn: u32, nOut: u32, stride: u32 };
|
|
54
57
|
@group(0) @binding(0) var<uniform> p: Params;
|
|
55
58
|
@group(0) @binding(1) var<storage, read> x: array<f32>; // (batch, cIn, L)
|
|
@@ -73,4 +76,4 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
73
76
|
}
|
|
74
77
|
out[(b * p.length + t) * p.nOut + o] = acc;
|
|
75
78
|
}
|
|
76
|
-
`;function q(){return typeof navigator<"u"&&!!navigator.gpu}var N=null;function Z(){return N||(N=(async()=>{if(!q())return!1;try{return await navigator.gpu.requestAdapter()!==null}catch{return!1}})(),N)}var X=class{weights;state=null;constructor(e){this.weights=e}async init(){if(this.state)return this.state;if(!q())throw new Error("WebGPU is not available in this environment");let e=await navigator.gpu.requestAdapter();if(!e)throw new Error("No WebGPU adapter available");let n=await e.requestDevice(),r=(a,u)=>{let c=n.createBuffer({size:Math.max(4,a.byteLength),usage:u,mappedAtCreation:!0});return new Float32Array(c.getMappedRange()).set(a),c.unmap(),c},f=GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,t=this.weights,o=[t.conv1,t.conv2,t.conv3,...t.layers===4&&t.conv4?[t.conv4]:[]].map(a=>({w:r(a.w.data,f),b:r(a.b,f)}));return this.state={device:n,embedModule:n.createShaderModule({code:Ae}),convModule:n.createShaderModule({code:ee}),headModule:n.createShaderModule({code:ne}),embedBuf:r(t.embed.data,f),convBufs:o,bioBuf:{w:r(t.bio.w.data,f),b:r(t.bio.b,f)},clsBuf:{w:r(t.cls.w.data,f),b:r(t.cls.b,f)}},this.state}async run(e,n,r){let f=await this.init(),{device:t}=f,s=this.weights,o=s.embed.shape[1],a=GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC,u=GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,c=t.createBuffer({size:e.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,mappedAtCreation:!0});new Int32Array(c.getMappedRange()).set(e),c.unmap();let v=C=>{let w=t.createBuffer({size:C.byteLength,usage:u,mappedAtCreation:!0});return new Uint32Array(w.getMappedRange()).set(C),w.unmap(),w},B=t.limits?.maxComputeWorkgroupsPerDimension??65535,g=C=>{let w=Math.max(1,Math.ceil(C/64)),Q=Math.min(w,B),H=Math.ceil(w/Q);return{x:Q,y:H,stride:Q*64}},D=(C,w,Q)=>{let H=t.createBindGroup({layout:C.getBindGroupLayout(0),entries:w}),L=t.createCommandEncoder(),E=L.beginComputePass();E.setPipeline(C),E.setBindGroup(0,H),E.dispatchWorkgroups(Q.x,Q.y),E.end(),t.queue.submit([L.finish()])},i=t.createBuffer({size:n*o*r*4,usage:a});{let C=g(n*r),w=v(new Uint32Array([n,r,o,s.embed.shape[0],C.stride])),Q=t.createComputePipeline({layout:"auto",compute:{module:f.embedModule,entryPoint:"main"}});D(Q,[{binding:0,resource:{buffer:w}},{binding:1,resource:{buffer:c}},{binding:2,resource:{buffer:f.embedBuf}},{binding:3,resource:{buffer:i}}],C)}let l=o,I=[s.conv1,s.conv2,s.conv3,...s.layers===4&&s.conv4?[s.conv4]:[]],P=t.createComputePipeline({layout:"auto",compute:{module:f.convModule,entryPoint:"main"}});for(let C=0;C<I.length;C++){let w=I[C],[Q,,H]=w.w.shape,L=C===2,E=C===3,m=E?4:L?s.dilation:1,j=E?Math.floor(8/2):L?Math.floor(s.dilation*2/2):C===0?1:2,AA=t.createBuffer({size:n*Q*r*4,usage:a}),eA=g(n*Q*r),hA=v(new Uint32Array([n,r,l,Q,H,j,m,1,eA.stride]));D(P,[{binding:0,resource:{buffer:hA}},{binding:1,resource:{buffer:i}},{binding:2,resource:{buffer:f.convBufs[C].w}},{binding:3,resource:{buffer:f.convBufs[C].b}},{binding:4,resource:{buffer:AA}}],eA),i=AA,l=Q}let h=t.createComputePipeline({layout:"auto",compute:{module:f.headModule,entryPoint:"main"}}),d=async(C,w)=>{let Q=t.createBuffer({size:n*r*w*4,usage:a}),H=g(n*r*w),L=v(new Uint32Array([n,r,l,w,H.stride]));D(h,[{binding:0,resource:{buffer:L}},{binding:1,resource:{buffer:i}},{binding:2,resource:{buffer:C.w}},{binding:3,resource:{buffer:C.b}},{binding:4,resource:{buffer:Q}}],H);let E=t.createBuffer({size:n*r*w*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ}),m=t.createCommandEncoder();m.copyBufferToBuffer(Q,0,E,0,n*r*w*4),t.queue.submit([m.finish()]),await E.mapAsync(GPUMapMode.READ);let j=new Float32Array(E.getMappedRange().slice(0));return E.unmap(),j},p=await d(f.bioBuf,s.bio.w.shape[0]),b=await d(f.clsBuf,s.cls.w.shape[0]);return{bio:p,cls:b}}};var dA={version:1,quantized:"int8_symmetric_per_tensor",layers:4,charset:["<pad>","<unk>"," ","!",'"',"#","%","'","(",")","+",",","-",".","/","0","1","2","3","4","5","6","7","8","9",":","=","?","@","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","{","}","~","\u0901","\u0902","\u0903","\u0905","\u0906","\u0907","\u0908","\u0909","\u090A","\u090F","\u0911","\u0913","\u0915","\u0916","\u0917","\u0918","\u091A","\u091B","\u091C","\u091D","\u091F","\u0920","\u0921","\u0922","\u0923","\u0924","\u0925","\u0926","\u0927","\u0928","\u092A","\u092B","\u092C","\u092D","\u092E","\u092F","\u0930","\u0932","\u0935","\u0936","\u0937","\u0938","\u0939","\u093C","\u093E","\u093F","\u0940","\u0941","\u0942","\u0947","\u0948","\u0949","\u094B","\u094C","\u094D","\u20B9"],classes:["O","SEP","RANGE","DIGITS","DOT","COMMA","PFX_PAAV","PFX_AADHA","PFX_PAUNE","PFX_SAVA","PFX_DEDH","PFX_DHAI","PFX_SAADHE","CARD_1","CARD_2","CARD_3","CARD_4","CARD_5","CARD_6","CARD_7","CARD_8","CARD_9","CARD_10","CARD_11","CARD_12","CARD_13","CARD_14","CARD_15","CARD_16","CARD_17","CARD_18","CARD_19","CARD_20","CARD_21","CARD_22","CARD_23","CARD_24","CARD_25","CARD_26","CARD_27","CARD_28","CARD_29","CARD_30","CARD_31","CARD_32","CARD_33","CARD_34","CARD_35","CARD_36","CARD_37","CARD_38","CARD_39","CARD_40","CARD_41","CARD_42","CARD_43","CARD_44","CARD_45","CARD_46","CARD_47","CARD_48","CARD_49","CARD_50","CARD_51","CARD_52","CARD_53","CARD_54","CARD_55","CARD_56","CARD_57","CARD_58","CARD_59","CARD_60","CARD_61","CARD_62","CARD_63","CARD_64","CARD_65","CARD_66","CARD_67","CARD_68","CARD_69","CARD_70","CARD_71","CARD_72","CARD_73","CARD_74","CARD_75","CARD_76","CARD_77","CARD_78","CARD_79","CARD_80","CARD_81","CARD_82","CARD_83","CARD_84","CARD_85","CARD_86","CARD_87","CARD_88","CARD_89","CARD_90","CARD_91","CARD_92","CARD_93","CARD_94","CARD_95","CARD_96","CARD_97","CARD_98","CARD_99","UNIT_SAU","UNIT_HAZAAR","UNIT_LAKH","UNIT_MILLION","UNIT_CRORE","UNIT_BILLION","UNIT_ARAB","UNIT_KHARAB"],embed:{shape:[114,16],scale:.04014205187559128,data_b64:"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"},conv1:{w:{shape:[32,16,3],scale:.006106450688093901,data_b64:"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"},b:[-.19965,.026515,.039484,-.57597,.30337,.26008,-.72519,-.10257,-.036593,.10559,-.040798,-.40242,-.099279,-.26205,-.22973,-.033645,-.49589,.15064,-.063868,.0065203,-.081652,.17027,.32479,.25103,-.074932,-.11914,.18076,.096649,.1548,.55641,-.32066,-.65784]},conv2:{w:{shape:[32,32,5],scale:.01006835512816906,data_b64:"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"},b:[-.48065,-.022214,-.14847,-.22966,-.19974,.52539,.98387,.59457,-.30747,-.076908,-.31714,.15821,.22441,-.237,.45228,-.10562,.186,-.15379,-.050172,.04386,1.1573,-.41681,.083819,-.24151,.28582,.54481,.79565,.068877,.45906,.10032,.17915,.3524]},conv3:{w:{shape:[32,32,3],scale:.012611277401447296,data_b64:"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"},b:[.17254,1.339,.4158,-.093339,.28021,-.046465,1.0513,.44342,1.0128,-.12751,-.87515,.64353,-.07254,1.0127,1.7885,1.6769,-.061762,.39241,-.26252,1.0561,.58258,-.23354,-.4736,.38796,.1319,.20964,.30156,1.8676,1.1334,-.093506,.71542,-.0054363]},conv4:{w:{shape:[32,32,3],scale:.021498816087841988,data_b64:"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"},b:[.039289,.34865,.95042,-.073607,1.4115,1.0756,.013808,.096819,.38295,.10098,-.18916,.169,2.1929,-.081778,.22036,.85779,-.44898,.21736,-.035547,.0096134,.7774,.22917,-.081477,.63055,.34935,1.9674,.54778,-.079256,.60878,.79962,.65425,1.9529]},bio:{w:{shape:[3,32],scale:.00724619859829545,data_b64:"/ugX9iQU9fzH9Qj7//n//VfnHw/rrPH+/xH4Kf72/gEB8RfuB/j8/Q33Bvvw/f71AX8BEgjz9gAE//kSBvn87fH1FwfQ4QX8R/YG+Q3+A/CstQgSJEHpAwcL++sI/PP1"},b:[.50217,-.69358,-.15374]},cls:{w:{shape:[120,32],scale:.010841965675354004,data_b64:"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"},b:[2.0176,.54879,-.74852,.6708,.39783,.50133,-.39469,.011433,.18709,-.17795,-.56959,-.41957,-.10239,-.20379,-.27652,-.23129,-.2993,-.59122,-.43887,-.21854,-.40505,-.32273,-.66862,-.36991,-.22728,-.015756,-.21333,-.54736,-.2546,-.30473,-.096751,-.33585,-.67811,-.60113,-.59227,-.50077,-.28001,-.62547,-.50637,-.69971,-.44887,-.24235,-.039837,-.17403,-.34016,-.16981,.053801,-.647,-.68176,-.50378,-.21779,-.19398,-.12628,-.28109,-.22943,-.36458,-.33458,-.32969,-.33054,-.06685,-.27666,-.30963,-.60442,-.47705,-.39358,-.18506,-.22168,-.31992,-.62064,-.49396,-.49137,-.29887,.056513,.083259,-.32745,-.43175,-.36524,-.56233,-.85284,-.53141,-.19461,-.032125,.18264,-.27448,.048796,-.115,-.469,-.25475,-.062195,-.099279,-.23322,-.62488,-.33195,-.25968,-.32699,-.27145,-.28322,-.063576,-.63915,-.14112,-.089139,-.66531,-.20493,-.27128,-.56956,-.4808,-.48607,-.45462,-.28481,-.36513,-.15753,-.65194,.28306,.072143,.026803,-.24859,.48548,-.0098499,.056588,-.34319]}};var Y=class{weights;charToId;gpu=null;defaultBackend;scratch;idsScratch=new Int32Array(M);bioIdsScratch=new Int32Array(128);clsIdsScratch=new Int32Array(128);bioProbsScratch=Array.from({length:128},()=>new Float32Array(3));constructor(e={}){this.weights=tA(e.weights??dA),this.charToId=sA(this.weights.charset),this.defaultBackend=e.backend??"cpu",this.scratch=new U(this.weights)}parse(e,n={}){let r=e;e=x(e);let f=r.length===e.length,t,s=oA(e.length);if(s.length===1&&s[0].length===e.length){let o=F(e.length),a=T(e,this.charToId,this.idsScratch,o),u=S(this.weights,a,this.scratch);t=this.decodeForward(e,u,0,e.length)}else{let o=[],a=new Set;for(let u of s){let c=e.slice(u.offset,u.offset+u.length),v=F(c.length),B=T(c,this.charToId,this.idsScratch,v),g=S(this.weights,B,this.scratch),D=this.decodeForward(c,g,u.offset,c.length);for(let i of D){let l=`${i.start}:${i.end}`;a.has(l)||(a.add(l),o.push(i))}}o.sort((u,c)=>u.start-c.start),t=o}if(f)for(let o of t)o.span=r.slice(o.start,o.end);return t}decodeForward(e,n,r,f=n.length){let t=f,s=t<=128,o=s?this.bioIdsScratch:new Int32Array(t),a=s?this.clsIdsScratch:new Int32Array(t),u=s?this.bioProbsScratch:Array.from({length:t},()=>new Float32Array(3));for(let B=0;B<t;B++)o[B]=J(n.bioLogits,B*3,3),a[B]=J(n.clsLogits,B*n.nCls,n.nCls),aA(n.bioLogits,B*3,3,u[B]);let c=CA(e,o.subarray(0,t),a.subarray(0,t),u),v=[];for(let B of c){let g=B.tokens.map(([l,I])=>[R[l],I]),D=wA(g),i=QA(e,B.start,B.end,te);v.push({span:B.text,start:B.start+r,end:B.end+r,value:D.value,...D.range?{range:D.range}:{},unit:D.unit??null,currency:i,confidence:B.confidence??0,classes:D.classes})}return v}async parseBatch(e,n={}){let r=n.backend??this.defaultBackend;if(!(r==="webgpu"||r==="auto"&&e.length>=32&&await Z()))return e.map(c=>this.parse(c,{backend:"cpu"}));let t=e,s=e.map(x),o=new Array(e.length),a=[],u=[];for(let c=0;c<s.length;c++)s[c].length<=128?a.push(c):u.push(c);for(let c of u)o[c]=this.parse(t[c],{backend:"cpu"});if(a.length>0){this.gpu||(this.gpu=new X(this.weights));let c=Math.max(...a.map(P=>s[P].length),1),v=F(c),B=a.length,g=new Int32Array(B*v),D=this.charToId.get("<pad>")??0;g.fill(D);for(let P=0;P<B;P++){let h=s[a[P]],d=T(h,this.charToId);g.set(d,P*v)}let{bio:i,cls:l}=await this.gpu.run(g,B,v),I=this.weights.cls.w.shape[0];for(let P=0;P<B;P++){let h=a[P],d=s[h],p=t[h],b=p.length===d.length,C=d.length,w=new Float32Array(C*3),Q=new Float32Array(C*I);for(let E=0;E<C;E++)w.set(i.subarray((P*v+E)*3,(P*v+E)*3+3),E*3),Q.set(l.subarray((P*v+E)*I,(P*v+E)*I+I),E*I);let H={bioLogits:w,clsLogits:Q,length:C,nCls:I},L=this.decodeForward(d,H,0,C);if(b)for(let E of L)E.span=p.slice(E.start,E.end);o[h]=L}}return o}},$=null;function IA(){return $||($=new Y),$}function pe(A,e={}){return IA().parse(A,e)}function Le(A,e={}){return IA().parseBatch(A,e)}function He(A={}){return new Y(A)}var te=lA(bA,EA);export{Y as Parser,He as createParser,q as isWebGPUAvailable,x as normalizeText,pe as parse,Le as parseBatch,Z as probeWebGPU};
|
|
79
|
+
`;function fA(){return typeof navigator<"u"&&!!navigator.gpu}var V=null;function sA(){return V||(V=(async()=>{if(!fA())return!1;try{return await navigator.gpu.requestAdapter()!==null}catch{return!1}})(),V)}var q=class{weights;state=null;constructor(e){this.weights=e}async init(){if(this.state)return this.state;if(!fA())throw new Error("WebGPU is not available in this environment");let e=await navigator.gpu.requestAdapter();if(!e)throw new Error("No WebGPU adapter available");let B=await e.requestDevice(),n=(s,g)=>{let P=B.createBuffer({size:Math.max(4,s.byteLength),usage:g,mappedAtCreation:!0});return new Float32Array(P.getMappedRange()).set(s),P.unmap(),P},t=GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,r=this.weights,f=r.conv.map(s=>({w:n(s.w.data,t),b:n(s.b,t)}));return this.state={device:B,embedModule:B.createShaderModule({code:ue}),convModule:B.createShaderModule({code:ce}),headModule:B.createShaderModule({code:Ee}),embedBuf:n(r.embed.data,t),convBufs:f,bioBuf:{w:n(r.bio.w.data,t),b:n(r.bio.b,t)},clsBuf:{w:n(r.cls.w.data,t),b:n(r.cls.b,t)}},this.state}async run(e,B,n){let t=await this.init(),{device:r}=t,f=this.weights,s=f.embed.shape[1],g=GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC,P=GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,o=r.createBuffer({size:e.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,mappedAtCreation:!0});new Int32Array(o.getMappedRange()).set(e),o.unmap();let w=a=>{let c=r.createBuffer({size:a.byteLength,usage:P,mappedAtCreation:!0});return new Uint32Array(c.getMappedRange()).set(a),c.unmap(),c},D=r.limits?.maxComputeWorkgroupsPerDimension??65535,C=a=>{let c=Math.max(1,Math.ceil(a/64)),E=Math.min(c,D),H=Math.ceil(c/E);return{x:E,y:H,stride:E*64}},u=(a,c,E)=>{let H=r.createBindGroup({layout:a.getBindGroupLayout(0),entries:c}),d=r.createCommandEncoder(),h=d.beginComputePass();h.setPipeline(a),h.setBindGroup(0,H),h.dispatchWorkgroups(E.x,E.y),h.end(),r.queue.submit([d.finish()])},v=r.createBuffer({size:B*s*n*4,usage:g});{let a=C(B*n),c=w(new Uint32Array([B,n,s,f.embed.shape[0],a.stride])),E=r.createComputePipeline({layout:"auto",compute:{module:t.embedModule,entryPoint:"main"}});u(E,[{binding:0,resource:{buffer:c}},{binding:1,resource:{buffer:o}},{binding:2,resource:{buffer:t.embedBuf}},{binding:3,resource:{buffer:v}}],a)}let I=s,l=f.conv,Q=r.createComputePipeline({layout:"auto",compute:{module:t.convModule,entryPoint:"main"}});for(let a=0;a<l.length;a++){let c=l[a],[E,,H]=c.w.shape,d=c.dilation,h=c.padding,U=r.createBuffer({size:B*E*n*4,usage:g}),Y=C(B*E*n),UA=w(new Uint32Array([B,n,I,E,H,h,d,1,c.residual?1:0,Y.stride]));u(Q,[{binding:0,resource:{buffer:UA}},{binding:1,resource:{buffer:v}},{binding:2,resource:{buffer:t.convBufs[a].w}},{binding:3,resource:{buffer:t.convBufs[a].b}},{binding:4,resource:{buffer:U}}],Y),v=U,I=E}let b=r.createComputePipeline({layout:"auto",compute:{module:t.headModule,entryPoint:"main"}}),i=async(a,c)=>{let E=r.createBuffer({size:B*n*c*4,usage:g}),H=C(B*n*c),d=w(new Uint32Array([B,n,I,c,H.stride]));u(b,[{binding:0,resource:{buffer:d}},{binding:1,resource:{buffer:v}},{binding:2,resource:{buffer:a.w}},{binding:3,resource:{buffer:a.b}},{binding:4,resource:{buffer:E}}],H);let h=r.createBuffer({size:B*n*c*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ}),U=r.createCommandEncoder();U.copyBufferToBuffer(E,0,h,0,B*n*c*4),r.queue.submit([U.finish()]),await h.mapAsync(GPUMapMode.READ);let Y=new Float32Array(h.getMappedRange().slice(0));return h.unmap(),Y},M=await i(t.bioBuf,f.bio.w.shape[0]),L=await i(t.clsBuf,f.cls.w.shape[0]);return{bio:M,cls:L}}};var xA={version:2,quantized:"int8_symmetric_per_tensor",charset:["<pad>","<unk>"," ","!",'"',"#","%","'","(",")","+",",","-",".","/","0","1","2","3","4","5","6","7","8","9",":","=","?","@","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","{","}","~","\u0901","\u0902","\u0903","\u0905","\u0906","\u0907","\u0908","\u0909","\u090A","\u090F","\u0911","\u0913","\u0914","\u0915","\u0916","\u0917","\u0918","\u091A","\u091B","\u091C","\u091D","\u091F","\u0920","\u0921","\u0922","\u0923","\u0924","\u0925","\u0926","\u0927","\u0928","\u092A","\u092B","\u092C","\u092D","\u092E","\u092F","\u0930","\u0932","\u0935","\u0936","\u0937","\u0938","\u0939","\u093C","\u093E","\u093F","\u0940","\u0941","\u0942","\u0947","\u0948","\u0949","\u094B","\u094C","\u094D","\u20B9"],classes:["O","SEP","RANGE","DIGITS","DOT","COMMA","PFX_PAAV","PFX_AADHA","PFX_PAUNE","PFX_SAVA","PFX_DEDH","PFX_DHAI","PFX_SAADHE","CARD_1","CARD_2","CARD_3","CARD_4","CARD_5","CARD_6","CARD_7","CARD_8","CARD_9","CARD_10","CARD_11","CARD_12","CARD_13","CARD_14","CARD_15","CARD_16","CARD_17","CARD_18","CARD_19","CARD_20","CARD_21","CARD_22","CARD_23","CARD_24","CARD_25","CARD_26","CARD_27","CARD_28","CARD_29","CARD_30","CARD_31","CARD_32","CARD_33","CARD_34","CARD_35","CARD_36","CARD_37","CARD_38","CARD_39","CARD_40","CARD_41","CARD_42","CARD_43","CARD_44","CARD_45","CARD_46","CARD_47","CARD_48","CARD_49","CARD_50","CARD_51","CARD_52","CARD_53","CARD_54","CARD_55","CARD_56","CARD_57","CARD_58","CARD_59","CARD_60","CARD_61","CARD_62","CARD_63","CARD_64","CARD_65","CARD_66","CARD_67","CARD_68","CARD_69","CARD_70","CARD_71","CARD_72","CARD_73","CARD_74","CARD_75","CARD_76","CARD_77","CARD_78","CARD_79","CARD_80","CARD_81","CARD_82","CARD_83","CARD_84","CARD_85","CARD_86","CARD_87","CARD_88","CARD_89","CARD_90","CARD_91","CARD_92","CARD_93","CARD_94","CARD_95","CARD_96","CARD_97","CARD_98","CARD_99","UNIT_SAU","UNIT_HAZAAR","UNIT_LAKH","UNIT_MILLION","UNIT_CRORE","UNIT_BILLION","UNIT_ARAB","UNIT_KHARAB"],embed_dim:16,channels:48,embed:{shape:[115,16],scale:.037109747529029846,data_b64:"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"},conv:[{k:5,dilation:1,residual:!1,w:{shape:[48,16,5],scale:.0056425235234200954,data_b64:"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"},b:[-.24382,-.38407,-.17817,-.351,-.22238,-.0019299,.028242,-.32424,-.21751,-.039856,-.006906,.12596,-.51106,.050427,.15754,.092282,-.29897,-.62661,-.0011282,-.7889,-.13757,.19859,-.055453,-.46586,-.038519,-.46619,.029959,-.0023833,-.30013,-.51659,-57684e-8,-.19363,-.10826,-.0072604,-.55949,.039256,-.28819,-.31607,1372e-7,-.063139,-.052011,-.12956,-.22692,-.51442,.16734,-.55926,.027049,-.51846]},{k:3,dilation:1,residual:!0,w:{shape:[48,48,3],scale:.013383498415350914,data_b64:"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"},b:[.11358,.11704,-.088201,-.033611,-.002863,.066441,.21947,.3986,-.12785,.46101,.26606,.1678,.17644,.49194,.36484,.3702,-.028757,.043993,-.032994,.45611,.06581,-.087146,.062385,.033713,.14835,.21905,.26361,-.10899,.29428,.48339,-.067757,.28667,.2584,-.10572,-.029867,.62242,-.16582,.19591,.20494,.15142,.42574,.21697,.023204,.21846,.019266,-.092303,.17447,.071329]},{k:3,dilation:2,residual:!0,w:{shape:[48,48,3],scale:.010257013142108917,data_b64:"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"},b:[.19117,-.074236,-.042869,.23032,.014854,-.33218,-.27652,.5013,-.1957,.25585,.66936,-.033494,.2669,.57471,.51624,.44239,.04774,.069218,.63188,.39761,-.089879,.99325,-.048568,-.23978,-.07374,.10848,-.27321,-.18405,.22888,1.0015,.16014,.14434,.09867,-.16617,.32079,.45812,.28912,.58278,1.0206,.20699,.39127,.13378,-.066438,.084532,-.014646,.68524,.10335,.14651]},{k:3,dilation:4,residual:!0,w:{shape:[48,48,3],scale:.01723182387650013,data_b64:"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"},b:[1.7206,.31359,-.2062,.93225,.2975,-1.3697,.17743,.72685,-.81717,.28116,.62245,.038487,.65606,.65371,.59583,.74065,-.14375,.1782,.38128,.090745,.23095,-.074912,.06153,.12158,.018713,.34466,.25065,.24443,-.10432,1.8078,.77921,.54224,-.1821,.47568,.74781,.58168,.02778,.32489,1.0448,-.077362,.32227,-.047404,-.33059,-.039291,.23171,1.0791,.16394,-.043724]},{k:3,dilation:8,residual:!0,w:{shape:[48,48,3],scale:.02836204320192337,data_b64:"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"},b:[.40977,.59899,.21644,.22858,1.5047,.2282,1.0961,1.5619,.70156,-1.3602,-.14413,.35846,-.093414,.16863,1.7523,.58493,.69916,.20671,1.4914,.4477,.4493,.32447,.10877,-.72769,.098431,.79216,-.0092255,.35221,.18134,1.5414,.43936,.038611,.20285,.52693,-.65092,.48794,.7451,.045148,.36787,.21284,-1.3916,-2.2047,.010128,.39447,.085648,-.43788,.017951,.31546]}],bio:{w:{shape:[3,48],scale:.004223219584673643,data_b64:"9BAP/t/w+yvAGv0LF/b6/RH3Nv4BWwfyFq/xBfcPCf309Q4I7RITBnex0/fV+Qwa8g4PAADx+u74GfwK//b0HBH5AfwA+wr1Ff74Bfj8CQHy8wz07xMTBgUeAfsO9w0c8w0PACjy+bMuF/0M8vb32RL50f4AqQr3FUT/BPfrCQ3x8w3j7BQTBp1/MfxB+BQb"},b:[.3298,-1.0277,-.017153]},cls:{w:{shape:[120,48],scale:.004936628974974155,data_b64:"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"},b:[2.1812,1.1932,-.12909,.99489,-1.0059,-1.5953,-.73583,-.11399,.73543,.30603,-.61356,.014246,.51264,-.22961,-.77544,.47317,-.036083,.41667,-.2461,-.89269,-.30756,-.84472,-.82134,-.46859,-.87589,-.3564,-1.2778,-.43376,-.31977,-.47586,-.31124,-.59335,-.28646,-.94846,-.53685,-.60465,-1.015,-.36367,-.87949,-.38464,-.2511,-.42145,-.50176,-.66217,-.42143,-.1735,-.36331,-.19983,-.25013,-.43281,-.35854,-.44943,-.53251,-.75929,-.42566,.054378,-.62883,.090769,-.62326,-.34156,-.68823,-.21448,-.60644,-.5597,-.86791,-.48415,-.83884,-.6919,-.48049,-.47518,-.14021,-.35018,-.7899,-.025957,-.44889,-.38806,-.35918,-.29211,-.22144,-.47468,-.43834,-.53023,-.49121,-.30336,-.49787,-.44441,-.46111,-.55548,-.21931,-.80624,-.19708,-.39377,-.59085,-.64261,-.34571,-.49424,-.27933,.12296,-.46782,-.38657,-.57408,-.29697,-.76351,-.54065,-.78931,-.96345,-.2801,-.44264,-.33914,-.68746,-.11425,-.29714,-.15539,.84044,1.1134,-.40905,.44269,.36281,-.58235,-.017571]}};var $=class{weights;charToId;gpu=null;defaultBackend;scratch;idsScratch=new Int32Array(R);bioIdsScratch=new Int32Array(128);clsIdsScratch=new Int32Array(128);bioProbsScratch=Array.from({length:128},()=>new Float32Array(3));constructor(e={}){this.weights=oA(e.weights??xA),this.charToId=wA(this.weights.charset),this.defaultBackend=e.backend??"cpu",this.scratch=new j(this.weights)}parse(e,B={}){if(typeof e!="string")return[];let n=e;e=k(e);let t=n.length===e.length,r,f=eA(e.length);if(f.length===1&&f[0].length===e.length){let s=x(e.length),g=z(e,this.charToId,this.idsScratch,s),P=S(this.weights,g,this.scratch);r=this.decodeForward(e,P,0,e.length)}else{let s=[],g=new Set;for(let P of f){let o=e.slice(P.offset,P.offset+P.length),w=x(o.length),D=z(o,this.charToId,this.idsScratch,w),C=S(this.weights,D,this.scratch),u=this.decodeForward(o,C,P.offset,o.length);for(let v of u){let I=`${v.start}:${v.end}`;g.has(I)||(g.add(I),s.push(v))}}s.sort((P,o)=>P.start-o.start),r=s}if(t)for(let s of r)s.span=n.slice(s.start,s.end);return r}decodeForward(e,B,n,t=B.length){let r=t,f=r<=128,s=f?this.bioIdsScratch:new Int32Array(r),g=f?this.clsIdsScratch:new Int32Array(r),P=f?this.bioProbsScratch:Array.from({length:r},()=>new Float32Array(3));for(let D=0;D<r;D++)s[D]=p(B.bioLogits,D*3,3),g[D]=p(B.clsLogits,D*B.nCls,B.nCls),BA(B.bioLogits,D*3,3,P[D]);let o=HA(e,s.subarray(0,r),g.subarray(0,r),P),w=[];for(let D of o){let C=D.tokens.map(([I,l])=>[F[I],l]),u=LA(e,D.start,D.end,ie);if(dA(C)&&u===null)continue;let v=MA(C);w.push({span:D.text,start:D.start+n,end:D.end+n,value:v.value,...v.range?{range:v.range}:{},unit:v.unit??null,currency:u,confidence:D.confidence??0,classes:v.classes})}return w}inspect(e){let B=performance.now();typeof e!="string"&&(e="");let n=k(e),t=eA(n.length),r=new Array(n.length),f=new Array(n.length).fill(!1);for(let P of t){let o=n.slice(P.offset,P.offset+P.length),w=x(o.length),D=z(o,this.charToId,this.idsScratch,w),C=S(this.weights,D,this.scratch);for(let u=0;u<o.length;u++){let v=P.offset+u;if(f[v])continue;f[v]=!0;let I=p(C.bioLogits,u*3,3),l=new Float32Array(3);BA(C.bioLogits,u*3,3,l);let Q=p(C.clsLogits,u*C.nCls,C.nCls);r[v]={ch:o[u],bio:I,bioProb:[l[0],l[1],l[2]],cls:F[Q],clsId:Q}}}let s=this.parse(e),g=performance.now()-B;return{text:n,chars:r,spans:s,ms:g}}modelInfo(){let e=this.weights,B=e.embed.data.length;for(let t of e.conv)B+=t.w.data.length+t.b.length;B+=e.bio.w.data.length+e.bio.b.length,B+=e.cls.w.data.length+e.cls.b.length;let n=e.conv.length?Math.max(...e.conv.map(t=>t.w.shape[0])):e.embed.shape[1];return{version:e.version,params:B,channels:n,embedDim:e.embed.shape[1],vocab:e.embed.shape[0],classes:e.classes.length,layers:e.conv.map(t=>({k:t.k,dilation:t.dilation,residual:t.residual}))}}async parseBatch(e,B={}){e=e.map(o=>typeof o=="string"?o:"");let n=B.backend??this.defaultBackend;if(!(n==="webgpu"||n==="auto"&&e.length>=32&&await sA()))return e.map(o=>this.parse(o,{backend:"cpu"}));let r=e,f=e.map(k),s=new Array(e.length),g=[],P=[];for(let o=0;o<f.length;o++)f[o].length<=128?g.push(o):P.push(o);for(let o of P)s[o]=this.parse(r[o],{backend:"cpu"});if(g.length>0){this.gpu||(this.gpu=new q(this.weights));let o=Math.max(...g.map(Q=>f[Q].length),1),w=x(o),D=g.length,C=new Int32Array(D*w),u=this.charToId.get("<pad>")??0;C.fill(u);for(let Q=0;Q<D;Q++){let b=f[g[Q]],i=z(b,this.charToId);C.set(i,Q*w)}let{bio:v,cls:I}=await this.gpu.run(C,D,w),l=this.weights.cls.w.shape[0];for(let Q=0;Q<D;Q++){let b=g[Q],i=f[b],M=r[b],L=M.length===i.length,a=i.length,c=new Float32Array(a*3),E=new Float32Array(a*l);for(let h=0;h<a;h++)c.set(v.subarray((Q*w+h)*3,(Q*w+h)*3+3),h*3),E.set(I.subarray((Q*w+h)*l,(Q*w+h)*l+l),h*l);let H={bioLogits:c,clsLogits:E,length:a,nCls:l},d=this.decodeForward(i,H,0,a);if(L)for(let h of d)h.span=M.slice(h.start,h.end);s[b]=d}}return s}},gA=null;function AA(){return gA||(gA=new $),gA}function Xe(A,e={}){return AA().parse(A,e)}function Ne(A,e={}){return AA().parseBatch(A,e)}function je(A){return AA().inspect(A)}function Se(){return AA().modelInfo()}function Je(A={}){return new $(A)}var ie=FA(RA,OA);export{F as CLASSES,$ as Parser,Je as createParser,je as inspect,fA as isWebGPUAvailable,Se as modelInfo,k as normalizeText,Xe as parse,Ne as parseBatch,sA as probeWebGPU};
|
package/dist/types.d.ts
CHANGED
|
@@ -146,4 +146,122 @@ export interface WeightsJsonInt8 {
|
|
|
146
146
|
b: number[];
|
|
147
147
|
};
|
|
148
148
|
}
|
|
149
|
-
|
|
149
|
+
/** v2 conv layer entry, float form. */
|
|
150
|
+
export interface ConvLayerJsonFloat {
|
|
151
|
+
k: number;
|
|
152
|
+
dilation: number;
|
|
153
|
+
residual: boolean;
|
|
154
|
+
w: {
|
|
155
|
+
shape: number[];
|
|
156
|
+
data: number[];
|
|
157
|
+
};
|
|
158
|
+
b: {
|
|
159
|
+
shape: number[];
|
|
160
|
+
data: number[];
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/** v2 conv layer entry, int8 form. */
|
|
164
|
+
export interface ConvLayerJsonInt8 {
|
|
165
|
+
k: number;
|
|
166
|
+
dilation: number;
|
|
167
|
+
residual: boolean;
|
|
168
|
+
w: {
|
|
169
|
+
shape: number[];
|
|
170
|
+
scale: number;
|
|
171
|
+
data_b64: string;
|
|
172
|
+
};
|
|
173
|
+
b: number[];
|
|
174
|
+
}
|
|
175
|
+
/** Weights JSON version 2, float form: an explicit ordered `conv` layer list
|
|
176
|
+
* instead of the hard-coded conv1..conv4 fields. See CONTRACT.md section 2. */
|
|
177
|
+
export interface WeightsJsonV2Float {
|
|
178
|
+
version: 2;
|
|
179
|
+
charset: string[];
|
|
180
|
+
classes: string[];
|
|
181
|
+
embed_dim?: number;
|
|
182
|
+
channels?: number;
|
|
183
|
+
embed: {
|
|
184
|
+
shape: number[];
|
|
185
|
+
data: number[];
|
|
186
|
+
};
|
|
187
|
+
conv: ConvLayerJsonFloat[];
|
|
188
|
+
bio: {
|
|
189
|
+
w: {
|
|
190
|
+
shape: number[];
|
|
191
|
+
data: number[];
|
|
192
|
+
};
|
|
193
|
+
b: {
|
|
194
|
+
shape: number[];
|
|
195
|
+
data: number[];
|
|
196
|
+
};
|
|
197
|
+
};
|
|
198
|
+
cls: {
|
|
199
|
+
w: {
|
|
200
|
+
shape: number[];
|
|
201
|
+
data: number[];
|
|
202
|
+
};
|
|
203
|
+
b: {
|
|
204
|
+
shape: number[];
|
|
205
|
+
data: number[];
|
|
206
|
+
};
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
/** Weights JSON version 2, int8 form. */
|
|
210
|
+
export interface WeightsJsonV2Int8 {
|
|
211
|
+
version: 2;
|
|
212
|
+
quantized: string;
|
|
213
|
+
charset: string[];
|
|
214
|
+
classes: string[];
|
|
215
|
+
embed_dim?: number;
|
|
216
|
+
channels?: number;
|
|
217
|
+
embed: {
|
|
218
|
+
shape: number[];
|
|
219
|
+
scale: number;
|
|
220
|
+
data_b64: string;
|
|
221
|
+
};
|
|
222
|
+
conv: ConvLayerJsonInt8[];
|
|
223
|
+
bio: {
|
|
224
|
+
w: {
|
|
225
|
+
shape: number[];
|
|
226
|
+
scale: number;
|
|
227
|
+
data_b64: string;
|
|
228
|
+
};
|
|
229
|
+
b: number[];
|
|
230
|
+
};
|
|
231
|
+
cls: {
|
|
232
|
+
w: {
|
|
233
|
+
shape: number[];
|
|
234
|
+
scale: number;
|
|
235
|
+
data_b64: string;
|
|
236
|
+
};
|
|
237
|
+
b: number[];
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
export type WeightsJson = WeightsJsonFloat | WeightsJsonInt8 | WeightsJsonV2Float | WeightsJsonV2Int8;
|
|
241
|
+
export interface CharTag {
|
|
242
|
+
ch: string;
|
|
243
|
+
bio: 0 | 1 | 2;
|
|
244
|
+
bioProb: [number, number, number];
|
|
245
|
+
cls: string;
|
|
246
|
+
clsId: number;
|
|
247
|
+
}
|
|
248
|
+
export interface Inspection {
|
|
249
|
+
/** normalized text (see normalizeText()) */
|
|
250
|
+
text: string;
|
|
251
|
+
chars: CharTag[];
|
|
252
|
+
spans: Sankhya[];
|
|
253
|
+
ms: number;
|
|
254
|
+
}
|
|
255
|
+
export interface ModelInfo {
|
|
256
|
+
version: number;
|
|
257
|
+
params: number;
|
|
258
|
+
channels: number;
|
|
259
|
+
embedDim: number;
|
|
260
|
+
vocab: number;
|
|
261
|
+
classes: number;
|
|
262
|
+
layers: Array<{
|
|
263
|
+
k: number;
|
|
264
|
+
dilation: number;
|
|
265
|
+
residual: boolean;
|
|
266
|
+
}>;
|
|
267
|
+
}
|
package/dist/weights.d.ts
CHANGED
|
@@ -4,22 +4,27 @@ export interface Tensor {
|
|
|
4
4
|
data: Float32Array;
|
|
5
5
|
}
|
|
6
6
|
export interface ConvLayer {
|
|
7
|
+
k: number;
|
|
8
|
+
dilation: number;
|
|
9
|
+
residual: boolean;
|
|
10
|
+
padding: number;
|
|
11
|
+
w: Tensor;
|
|
12
|
+
b: Float32Array;
|
|
13
|
+
}
|
|
14
|
+
export interface HeadLayer {
|
|
7
15
|
w: Tensor;
|
|
8
16
|
b: Float32Array;
|
|
9
17
|
}
|
|
10
18
|
export interface LoadedWeights {
|
|
11
|
-
|
|
12
|
-
dilation: number;
|
|
19
|
+
version: number;
|
|
13
20
|
charset: string[];
|
|
14
21
|
classes: string[];
|
|
15
22
|
embed: Tensor;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
conv4?: ConvLayer;
|
|
20
|
-
bio: ConvLayer;
|
|
21
|
-
cls: ConvLayer;
|
|
23
|
+
conv: ConvLayer[];
|
|
24
|
+
bio: HeadLayer;
|
|
25
|
+
cls: HeadLayer;
|
|
22
26
|
}
|
|
23
|
-
/** Load
|
|
24
|
-
* python/sankhya/export.py) into
|
|
27
|
+
/** Load a v1 or v2, float or int8, weights JSON (as written by
|
|
28
|
+
* python/sankhya/export.py) into a normalised LoadedWeights with an ordered
|
|
29
|
+
* `conv` layer list. See CONTRACT.md section 2. */
|
|
25
30
|
export declare function loadWeights(json: WeightsJson): LoadedWeights;
|