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 CHANGED
@@ -1,7 +1,7 @@
1
1
  # gpu-sankhya
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/gpu-sankhya.svg)](https://www.npmjs.com/package/gpu-sankhya)
4
- [![bundle size](https://img.shields.io/badge/bundle-27%20KB%20gzipped-blue)](https://www.npmjs.com/package/gpu-sankhya?activeTab=code)
4
+ [![bundle size](https://img.shields.io/badge/bundle-47.2%20KB%20gzipped-blue)](https://www.npmjs.com/package/gpu-sankhya?activeTab=code)
5
5
  [![license](https://img.shields.io/npm/l/gpu-sankhya.svg)](./LICENSE)
6
6
  [![demo](https://img.shields.io/badge/demo-live-brightgreen)](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 (27 KB gzipped) int8-quantized default model inlined
25
- in the package — `import { parse } from "gpu-sankhya"` works with no
26
- network fetch. Zero runtime dependencies.
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 — roughly 0.8M multiply-adds through a 4-layer,
160
- 32-channel char CNN — and runs in about 1.5 ms in plain JS. A WebGPU
161
- dispatch has fixed overhead of a few milliseconds (device/pipeline setup,
162
- buffer upload, queue submit, readback), which dwarfs that per-string cost.
163
- So the GPU only pays off once you're amortizing that overhead over a
164
- batch hundreds of strings at once which is exactly what `parseBatch`
165
- does with `backend: "auto"`/`"webgpu"`; `parse()` stays CPU-only and
166
- synchronous on purpose.
167
-
168
- The WebGPU path has been verified on a real GPU in desktop Chrome: on the
169
- demo page's batch benchmark (500 varied strings) it matches the CPU
170
- backend span-for-span (500/500) and runs about 1.6x faster. The demo's
171
- benchmark re-runs that comparison on every click, so any regression shows
172
- up as a mismatch count rather than a silent wrong answer.
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: 18,811 parameters, 4 conv layers (kernel sizes
177
- 3/5/3/3, dilations 1/1/2/4, 32 channels), 16-dim char embeddings over a
178
- 114-character vocab (union of the `hi_latn` and `hi_deva` packs). Trained
179
- 20 epochs (~12 minutes on 4 CPU cores) on 200,000 synthetic examples
180
- generated from both language packs' grammars, mixed 0.55/0.45 with a 10%
181
- cross-pack share (see `python/README.md`).
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.92 value accuracy. This number is optimistic — it's testing
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, 180 sentences / 161 spans) and
189
- `python/tests/gold_deva.jsonl` (Devanagari Hindi, 166 sentences / 141
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) | 180 | 161 | 0.9441 | 0.9222 | 0.9565 | 0.9390 |
195
- | gold_deva.jsonl (Devanagari) | 166 | 141 | 0.9645 | 0.9580 | 0.9716 | 0.9648 |
196
- | combined | 346 | 302 | 0.9536 | 0.9387 | 0.9636 | 0.9510 |
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 4-layer dilated conv1d stack (see Accuracy above) produces, per
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 16 pad tokens before
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=16`), because training always right-pads every
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
- (unusual typos, possessive apostrophes, long multi-term ranges,
284
- occasional spurious spans) are model-quality issues, not bugs in the
285
- arithmetic core, which is unit-tested directly and independently of the
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/` — a minimal textarea + live-results HTML 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 a minimal textarea + live-results demo that
341
- imports `dist/index.js` directly (no build step needed beyond `npm run
342
- build`).
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 = 16;
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
- `,ee=`
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
- `,ne=`
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:"Aw8a/vX5AyUp8tTGCxkNAevv58/+AwfzAwQGCxgbJSsfFCQPCA4B3uHt9O30CQYB9PT8Hwr4AuPiAQ0EBAQE/hAM7OP0B/8P/fP6Bf0F//r9HCUKCAIAB+LS9tfl+fAF6QAG++0HCgARCBHp+Ab79PYM8hQB/QILBvT2/goB6vQGCwkH7QwNBvMDAggL8f7+A/37Iw8REwsH8vj8AAEX6/39B/MA9Q4K/QH/BwX25PUF8gv++9r//xUC7wEDBBv2GBQQBQAO8dPK5J2n8P8J/vEF6egB+t3vAwX1CwwULSEU+goJyrfbCw4IGica7/8HAPHz6Mrq/e/nBSAU9PoOFgzt/+nh+ObuA/3+FhoV6uLv+OPqCBkk//ziBdjMAfnzEBMW8vbsyru/LzQtDRUWBAIM+gX9+wIFCw4RAA8L9vn9/gD0HSUpDf77DxMS8+vrAP3+5vL8BRQU/AT2DQrzCwULyeny8wAh3trl5vb0/hAn/fwJ/QoLGh8X8v3+CyEYA/8B6wPkqZgMQEQcDhj48v7x7tUJ6u/4IhoQ+/8K5t746f3yKzD7FhXh+v/r4cD3/w/3ztcIECfs/fLvBwL2Fggc4vD+DxYP2hEC7OsJ9xjbDAwX/wHzMSs18gr4DCYd/BEVAgMOCRIZ4NLG7fH9Bgr7B/IBAP0A8eHlAPsHDQ8LBw0S8/Lq+gLrAxEFBwgGAer6DgkN8/js+/kNBhX77/r/BQb8AwgQDhMHCgMEDQf59vP/BAf3/PflAAYK/O3x8/76BREGBPwE/N7RFv/7CAUGBBgHBfrx/QH0//wIFxAQAPT7zc/pAwYBEhcP7fv9/+H0xtXuBAQEAhQK+/kKDA3+Agb/+/MD990ACQH63uoA+fMCBAT8APXz/gADCBP8AAcK//sTBgD4+9DHvq7P//AE8fQB+/oDBhMGAgAQFh4WBBMP4N/q+w0LDBsTCggEBv33//H1Agj+//DxAgMN9f74+d2+8vLv+O/5BAkUAQkIHCH4/9zV//3t/dbc+PHwB/8NAA8VDQf278no/Pn2/vsH/xMIA/H5A/P0+vIBBfL/+OXp+Ab/6fX7BwIK+wQAAvT1EBUN+gEDDiEVBhIV7u339/Dl6fn+Au0A/PwFBw0KDAT+BAQB99vw/hEM/+zwCQbqDQbw+LXH/0JK3QcK/gMF+eLt9ff09RMJDBoF+dzZ/uT3Ey0TAwwT3Pb89eDoABAB6dTZ9AwO8vX/AQkINxj/A+TpKR/x79v0BgkA3vwOExAK9vb1BBQjGfwD9f8aBgX9/Rr196DL+wkF6f7uBwv++/kC//4E/PYP/xb/CfjsAvb3AAYKBP78CPfw9N/4CjsDAP4FAA8S/gkSAwP6BeoC/uId+C308hIA+uwAHArsDAwEBBQb+wMRCfDzA/b/FxcIA/Dt/+Lo777C+QES/ffqB/8G/NrUDwb6AAH6+/sS+iMb5+3y7ez6AwoLGRkMDiIq/w4DAvkG/e3tCRb6+OL0/e/5+/fpEfj4BA8H+AD5+PLwAPH29fvv//b89OH9+wsZ/BHtAePy/AIR8fQJ/QUXAfb8/BL//fkN/CH/AQL3/eQFBRkfAwUX9/kQ9fv9AxP+/frq//X5/v/z+wgEBhETA/b4CB/w/AD6+ffl+PgACAoF+/MHAhYGBe3uAw4Z+Ovy/QL/GCYQ8wQWDg0OCxYGDvf2CRUM8PgM/QcGEhULBwIHChQR/PoE8vgDCgcF/vr/7/HwAR8L9/j+9woK/w//9/715Pn3DQH9+v8BCwIEB/4E/wH3/v8G+vf6CQgHBhMW/AL4AQHtAAAN+Pb4/wcABwQD++/5AwcH/vH2/gD2Bfr+AQcC6+/0Bwj8/wH+AgYFAQPzAPwA/wsM/e31EgMKAwsD/wYTBQf8/g///f8C/v0I/gsJAgYHAf0B/QQFBPn9/Pf4C//48O0LDhMK/QUF8ez8BwLw++X1AAoLCwf/CAv++f/8ChAPDRAH9vH19+0AEREF9uf3/e3kAAcQ8PIB/xAQ+P8F//T1DBYE+QUOBBIGCgsE/Pb0/f0HCBIJ9fby+vzx/vkH9vn/9gT1+Pf69wH39fbx8f4D+Pn+Aff2Av71//f1+QX6APL9Bfv7+Pb+9vkCA/X/+P/y9QD++AD+9QAD/fgA//fy+fT1Av4A/wf//QL6Af0B9vQA+P0EGfXP9vQLCPf63MHjCgz//RQL8PAOCAHsC/LxCBoaDQf2ASEfEPLq+Aj6DPP7FgsE/wQLDAIF78vsFB/5/gYSEhbq5vIJ7uG48wUA9v4I+tX7Bxn4CAT39tPl/Pn/+efYFyEG9PUh3PgZDb+BMi4c8//44ugFDfX5HwzxAQ0WFhEODv8IHRPoAA0FGSUOAfQN+Qjn/Qsf+OfV+wv7BfwWGB4b9vgS3sWK1eX/zd3/AvbzCvz3BtPYC+PE+eHI/MrdCgoEBggQ8vYA9fIG6w4Z+fcO8vL89Qb8/vYE9xUV+O0K8/MBDAn+Dg0C7QENDRYLBgwF7v0D8+j35+3z7fgMC/n18LvaEekKDgT49CIi5wIK/+n0CP4eAenj+uwD9/787tvNAwgMDhsT79XfBP/+/gEK9xsPAQH6COjo9/n5Bf38CP0L8OTsAP/3AQcBAA8GBfIACAsT/fEHC/oH/ggG5un5AA4f7uoNChAGCAT8BwgI+vkB/+Ha/Pnz+hQI//vx9/8B+RoLAeDs//voBQH7/wYJ+/UBAvoB/vrzAvr56vD+//39/fYDDgn5DhQI8/0IBRP8GxQcAQIBAgH5AP/+Dfn89/TyBhD5+u0C+v354er8CQP6ARYYBQX7ABoLA//6CQwP+wr+AgIC+PP6+//7/Q/8BPcIAAMJAw8QBAD0IBYKCg4P+voGDAoHAgT1/wYGDBsGKiYW/QL6ABUFAO7q9O4B/fcCAhICAAUJAv/y6ODw+gEBAwsP9gEDAxAD/gDv+QEGBwoHABUL3MHeDAUH3uT6+uj/BOz/B/Ly8gABCgD4ISMfEQ71A/0IAPkEAQQJ7vj+CQMG9Pnx6u/9+gUVBv33AAkF7tzD9vv/1Pz9FAsC/PD8IxsMAOfh7On1EysK+wkHAPICAxQY99C/+PH7+O4F+QX9Awr1+vXxBQIH6OwLABMW1tr2yczuIiQR6O7/BPT9AQYT+/js/hQPAA8KFQ76AvwI+vL5+O0CCw0F7QIDCwX+CwoOAOno/fb3/QcBGxEA+vsE6NDl//PfAQcAAgUF+975CQcG/vv39ODnCgUCDzAhHisMEBUK8PT1BQIF+QoO//D3BxsLCxoY/QsDCwbz7O3v+vDb/v0F+/wD7fL7Fxr+Bf3yA/fp9/T4CAQBJBIN/vIAA/PrA/YQAxAH++8FDBkFAR37AhEXBf8B8PHw8wj9CQX8AgQAAQ0JEhcFCgAE/gf2/AkG9Pb4CQ4JDwz85ePpDwUKAff+9QAH7/oI9+oBARITAvb+/vMD9voIA/v0Bwb+6eL5EB0FAfz+AQP7+fgC/P4DAw7/CP/9AfX+9/sACf8BAwf++/b3//n9AwD95+sAAgYADA0KCgTxCQQCAf4CEv747PgIA/D8AwT5CAP+9/j5CQ0MCgj/+vYC+PIDAhj+Bvv6/u/o3+jmAO7xDBIL++3/BwMJ/RYE4fP5/gb99PMADQYIBAIB9/YCDjEFAgoN/QkK9uT1BAj1AfL/+eX3/xv2Cgz++fn8DhIA9en/BA8T/PsABAD6+vH1Eg4G/wYHBhsY8tnaC/Pv/xkDAvb+Bw4Q//X8BOPj8ff7/gICCQH3ERoWEAP9//0EBQUEGxkY//f+/gkIAvf2Gh4M8+TrBhHiCA0IAwH89e34+vj/BQcK+uT2/Qn//vP2/AD1APoSAAP968bXCAH5/QMLAAH9CRYJAQcIAfH45uzx/P0E7Orv8wH+CRINDBAQBwsGEf4H/fj7Bff/BAMK5eHx/vTy/P7uBgACBwMF7e0A+u/3Cv0A9O3o/RAS/fTz7AUSCiMTBuHY7AkP7+X0Dv70CvL+/+gSAQ0b+AH+BRQfC+rs6Oj3HxgK8wABDyUW/gn0+un6/ef3AfED9uwD6ecBAgkG8usOE/v4+A39/wwN8dkABPP78gf+/ywWBPP3"},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
- export type WeightsJson = WeightsJsonFloat | WeightsJsonInt8;
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
- layers: number;
12
- dilation: number;
19
+ version: number;
13
20
  charset: string[];
14
21
  classes: string[];
15
22
  embed: Tensor;
16
- conv1: ConvLayer;
17
- conv2: ConvLayer;
18
- conv3: ConvLayer;
19
- conv4?: ConvLayer;
20
- bio: ConvLayer;
21
- cls: ConvLayer;
23
+ conv: ConvLayer[];
24
+ bio: HeadLayer;
25
+ cls: HeadLayer;
22
26
  }
23
- /** Load either the float or int8 weights JSON (as written by
24
- * python/sankhya/export.py) into flat Float32Array tensors. */
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gpu-sankhya",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "description": "Fast char-CNN extraction of Hinglish and Devanagari Hindi numeric quantities, with CPU and WebGPU backends.",
6
6
  "license": "MIT",