gpu-sankhya 0.1.2 → 0.3.0

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,14 +1,17 @@
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
 
8
8
  Parses Indian informal number/currency shorthand — Hinglish (romanised
9
- Hindi) and Indian-English amount phrases like `sava lakh`, `dedh crore`,
10
- `2.5L`, `20k`, `2-3 lakh` — into a clean numeric value, with the span,
11
- unit, currency, and confidence that produced it.
9
+ Hindi), Devanagari Hindi, and Indian-English amount phrases like `sava
10
+ lakh`, `dedh crore`, `डेढ़ लाख`, `सवा करोड़`, `2.5L`, `20k`, `2-3 lakh` —
11
+ into a clean numeric value, with the span, unit, currency, and confidence
12
+ that produced it. Mixed-script input (Latin and Devanagari in the same
13
+ string, e.g. `"budget 2 लाख hai"`) is supported: currency and unit
14
+ detection scan both scripts' marker lists.
12
15
 
13
16
  A small char-level CNN tags each character of the input with a BIO span
14
17
  label and a semantic token class (digit, prefix word like "sava"/"dedh",
@@ -18,9 +21,10 @@ never predicts the value directly, so the arithmetic can't drift from the
18
21
  grammar (prefix semantics, additive descending units, multiplicative
19
22
  ascending units like `das hazaar crore` = 10,000 × 1 crore = 1e11, etc).
20
23
 
21
- Ships with a small (27 KB gzipped) int8-quantized default model inlined
22
- in the package — `import { parse } from "gpu-sankhya"` works with no
23
- 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.
24
28
 
25
29
  Model training lives in `python/` (a separate, actively-trained
26
30
  component); this package is the runtime that loads its exported weights.
@@ -65,6 +69,22 @@ parse("sawaa laakh ka budget hai");
65
69
  // variance ("sawaa"/"sava", "laakh"/"lakh") is part of the training data,
66
70
  // not special-cased.
67
71
 
72
+ // Devanagari input follows the same grammar/arithmetic as Hinglish (the
73
+ // core is language-independent -- see How it works); the expected output
74
+ // shape is identical, e.g.:
75
+ parse("डेढ़ लाख");
76
+ // [{ span: "डेढ़ लाख", value: 150000, unit: "lakh", ... }]
77
+
78
+ parse("सवा दो करोड़ का फ्लैट");
79
+ // [{ span: "सवा दो करोड़", value: 22500000, unit: "crore", ... }]
80
+
81
+ parse("बजट साढ़े तीन लाख है");
82
+ // [{ span: "साढ़े तीन लाख", value: 350000, unit: "lakh", ... }]
83
+ // NOTE: the correctness of these Devanagari examples depends on the
84
+ // bundled weights being trained on the hi_deva pack (see python/README.md);
85
+ // the runtime-side normalization/decoding/currency support is in place
86
+ // independent of which weights are loaded (createParser({ weights })).
87
+
68
88
  // batch (uses WebGPU automatically for large batches in a browser, else CPU)
69
89
  const results = await parseBatch(["sava lakh", "dedh crore", "..."]);
70
90
 
@@ -110,6 +130,29 @@ interface Sankhya {
110
130
  actually obtained. Result is cached, so repeated calls only probe once.
111
131
  `parseBatch`'s `"auto"` backend uses this (not `isWebGPUAvailable()`)
112
132
  to decide whether to try the GPU path.
133
+ - **`inspect(text) => Inspection`** — synchronous CPU inspection of the
134
+ raw model output before decode/repair: `{ text, chars: [{ch, bio,
135
+ bioProb, cls, clsId}], spans, ms }`, one entry per character with its
136
+ argmax BIO tag, BIO softmax probability, and predicted class. Useful
137
+ for debugging misclassifications or building a "what did the model
138
+ actually see" view (this is what powers the demo's per-character
139
+ panel); `parse()`'s decoded spans are the thing to use for normal
140
+ consumption.
141
+ - **`modelInfo() => ModelInfo`** — info about the currently loaded
142
+ default model: `{ version, params, channels, embedDim, vocab, classes,
143
+ layers: [{k, dilation, residual}] }`.
144
+ - **`CLASSES`** — the exported array of semantic token class names (the
145
+ same strings that appear in `Sankhya.classes` and `Inspection.chars[].cls`).
146
+ - **`normalizeText(text) => string`** — the exact normalization
147
+ `parse`/`parseBatch` apply before char-encoding (Unicode NFC, then
148
+ Devanagari digits U+0966-U+096F mapped 1:1 to ASCII `"0"`-`"9"`, then
149
+ lowercasing), exposed so callers can reproduce the same offsets. `parse`
150
+ returns `start`/`end` as indices into `normalizeText(text)`, not the raw
151
+ input — for the overwhelming majority of input, which already arrives in
152
+ NFC form, normalization never changes the string's length, so offsets
153
+ are unaffected; call `normalizeText` yourself first if you need to be
154
+ sure for non-NFC input. The `span` field is a substring of your original
155
+ input when lengths match, and of the normalized string otherwise.
113
156
 
114
157
  ## Backends
115
158
 
@@ -127,61 +170,91 @@ interface Sankhya {
127
170
 
128
171
  ### Why CPU by default
129
172
 
130
- One inference is small — roughly 0.8M multiply-adds through a 4-layer,
131
- 32-channel char CNN — and runs in about 1.5 ms in plain JS. A WebGPU
132
- dispatch has fixed overhead of a few milliseconds (device/pipeline setup,
133
- buffer upload, queue submit, readback), which dwarfs that per-string cost.
134
- So the GPU only pays off once you're amortizing that overhead over a
135
- batch hundreds of strings at once which is exactly what `parseBatch`
136
- does with `backend: "auto"`/`"webgpu"`; `parse()` stays CPU-only and
137
- synchronous on purpose.
138
-
139
- The WebGPU path has been verified on a real GPU in desktop Chrome: on the
140
- demo page's batch benchmark (500 varied strings) it matches the CPU
141
- backend span-for-span (500/500) and runs about 1.6x faster. The demo's
142
- benchmark re-runs that comparison on every click, so any regression shows
143
- up as a mismatch count rather than a silent wrong answer.
173
+ One inference is small — a 5-layer, 48-channel dilated/residual char
174
+ CNN, 39,579 parameters — and `parse()` runs in about 3.6 ms p50 (60-char
175
+ input) in plain JS; `parseBatch` on CPU averages about 4.0 ms/string over
176
+ 500 strings. A WebGPU dispatch has fixed overhead of a few milliseconds
177
+ (device/pipeline setup, buffer upload, queue submit, readback), which
178
+ dwarfs that per-string cost. So the GPU only pays off once you're
179
+ amortizing that overhead over a batch hundreds of strings at once —
180
+ which is exactly what `parseBatch` does with `backend: "auto"`/`"webgpu"`;
181
+ `parse()` stays CPU-only and synchronous on purpose.
182
+
183
+ The WebGPU path's plain (non-residual) conv layers have been verified on
184
+ a real GPU in desktop Chrome, matching the CPU backend span-for-span on
185
+ the demo page's batch benchmark. The current shipped model (arch `v2`)
186
+ adds a residual connection (`y = relu(conv(x)) + x`) on four of its five
187
+ layers; the WGSL shader's residual path is covered by unit tests that
188
+ check its structure but has not yet been re-verified against a real GPU
189
+ adapter in a browser — run the demo's batch benchmark yourself and check
190
+ for a 0 mismatch count before relying on it. The demo's benchmark re-runs
191
+ the CPU/WebGPU comparison on every click, so any regression shows up as a
192
+ mismatch count rather than a silent wrong answer.
144
193
 
145
194
  ## Accuracy
146
195
 
147
- The bundled default model: 17,883 parameters, 4 conv layers (kernel sizes
148
- 3/5/3/3, dilations 1/1/2/4, 32 channels), 16-dim char embeddings over a
149
- 56-character vocab. Trained 20 epochs (~9 minutes on 4 CPU cores) on
150
- 150,000 synthetic examples generated from the `hi_latn` language pack's
151
- grammar (see `python/README.md`).
196
+ The bundled default model (arch `v2`): 39,579 parameters, 5 conv layers
197
+ over 16-dim char embeddings a plain kernel-5 layer, then four residual
198
+ kernel-3 layers with dilations 1/2/4/8 (`y = relu(conv(x)) + x`), 48
199
+ channels, ±17-character receptive field over a 114-character vocab
200
+ (union of the `hi_latn` and `hi_deva` packs), 120 output classes. Trained
201
+ 20 epochs on 200,000 synthetic examples generated from both language
202
+ packs' grammars, mixed 0.55/0.45 with a 10% cross-pack share, plus
203
+ out-of-vocab "unk noise" augmentation so the model has actually seen
204
+ `<unk>` characters (emoji, CJK, Cyrillic, other symbols) during training
205
+ (see `python/README.md`). An older `v1` preset (the previously shipped
206
+ 4-layer, non-residual, 32-channel stack) is still loadable by both the
207
+ Python and JS runtimes for anyone using older exported weights.
152
208
 
153
209
  On synthetic validation data (drawn from the same generator/templates as
154
- training): 0.97 value accuracy. This number is optimistic — it's testing
210
+ training): 0.932 value accuracy. This number is optimistic — it's testing
155
211
  the model on its own distribution.
156
212
 
157
- On a hand-written gold set of 180 sentences / 161 spans
158
- (`python/tests/gold.jsonl`), written independently of the generator:
159
-
160
- | metric | value |
161
- | --- | --- |
162
- | value accuracy | 0.95 (153/161) |
163
- | span precision | 0.90 |
164
- | span recall | 0.96 |
165
- | span F1 | 0.93 |
166
-
167
- **The gold number is the one to trust.** Known miss categories, in rough
213
+ On two hand-written gold sets, written independently of the generator
214
+ `python/tests/gold.jsonl` (romanised Hindi, 184 sentences / 168 spans)
215
+ and `python/tests/gold_deva.jsonl` (Devanagari Hindi, 169 sentences / 141
216
+ spans) evaluated against the shipped int8-quantized weights:
217
+
218
+ | gold set | examples | spans | value accuracy | span precision | span recall | span F1 |
219
+ | --- | ---: | ---: | ---: | ---: | ---: | ---: |
220
+ | gold.jsonl (romanised) | 184 | 168 | 0.9515 | 0.8971 | 0.9515 | 0.9235 |
221
+ | gold_deva.jsonl (Devanagari) | 169 | 141 | 0.9861 | 0.9662 | 0.9931 | 0.9795 |
222
+ | combined | 353 | 309 | 0.9676 | 0.9288 | 0.9709 | 0.9494 |
223
+
224
+ Negatives (zero-gold-span examples, 55 total): 4 false positives (7.3%).
225
+ Per-category value accuracy: digits 0.977, words 0.964, prefix 0.948,
226
+ range 0.917, currency 0.979, multi_unit 1.0, symbol_unit 1.0,
227
+ mixed_script 1.0, long 0.75.
228
+
229
+ Compared to the previously shipped `v1` model (0.9441 / 0.9645 / 0.9536
230
+ combined value acc, F1 0.9510, 2/55 negatives false positives): this
231
+ model gains about 1.4 points of value accuracy and is materially more
232
+ robust to input containing characters outside its training vocabulary,
233
+ at the cost of slightly lower span precision — it produces a few more
234
+ spurious spans on unfamiliar words. That's a known, measured trade-off,
235
+ not an oversight.
236
+
237
+ **The gold numbers are the ones to trust.** Known miss categories, in rough
168
238
  order of frequency:
169
239
 
170
240
  - unusual typos the noise model doesn't cover (e.g. "croer" for "crore")
171
241
  - possessive apostrophes ("do lakh's")
172
- - long multi-term ranges ("paanch se sadhe saat lakh")
242
+ - long multi-term/mixed-numeral constructs ("three n half lakh", "50M")
243
+ - multi-number range phrases ("तीस पैंतीस हज़ार", "paanch se sadhe saat lakh")
173
244
  - occasional spurious spans triggered by unfamiliar words near number-ish
174
245
  context
175
246
 
176
247
  Reproduce these numbers yourself with
177
- `python -m sankhya.eval_gold --gold tests/gold.jsonl --weights-json src/data/default-weights.json --int8`
248
+ `python -m sankhya.eval_gold --gold tests/gold.jsonl tests/gold_deva.jsonl --weights-json src/data/default-weights.json --int8`
178
249
  from `python/` (see `python/README.md`).
179
250
 
180
251
  ## How it works
181
252
 
182
- 1. The input string is lowercased and char-encoded against the model's
183
- vocab (unknown chars map to `<unk>`).
184
- 2. A 4-layer dilated conv1d stack (see Accuracy above) produces, per
253
+ 1. The input string is normalized (`normalizeText`: Unicode NFC, then
254
+ Devanagari digits U+0966-U+096F mapped to ASCII `"0"`-`"9"`, then
255
+ lowercased byte-identical to the Python reference) and char-encoded
256
+ against the model's vocab (unknown chars map to `<unk>`).
257
+ 2. A dilated/residual conv1d stack (see Accuracy above) produces, per
185
258
  character, a 3-way BIO logit (O/B/I) and a class logit over the
186
259
  semantic token vocabulary (prefix words, cardinals, units, digits,
187
260
  separators, misc).
@@ -216,9 +289,9 @@ Raw per-character BIO/class predictions are cleaned up before evaluation:
216
289
  on the resulting token sequence.
217
290
 
218
291
  One more detail that matters more than it looks like it should: the
219
- runtime right-pads the character-id array with 16 pad tokens before
292
+ runtime right-pads the character-id array with 24 pad tokens before
220
293
  running the forward pass (mirroring `python/sankhya/np_infer.py`'s
221
- `pad_ids`/`PAD_TAIL=16`), because training always right-pads every
294
+ `pad_ids`/`PAD_TAIL=24`), because training always right-pads every
222
295
  example to the model's max length the same way. Running a short, tightly
223
296
  cropped input (e.g. the bare 4 characters of `"2.5L"`) without that
224
297
  padding measurably corrupts predictions — the model was never trained on
@@ -227,11 +300,20 @@ outputs are discarded; only the real characters' predictions are used.
227
300
 
228
301
  ## Limitations
229
302
 
230
- - **Latin-script Hindi only.** Only Hinglish / romanised Hindi and Indian
231
- English amount phrases are supported today. Devanagari script and other
232
- Indian languages are planned via additional language packs (the
233
- arithmetic core is already language-independent; only the class
234
- vocabulary and currency-marker lists are per-language) see Roadmap.
303
+ - **Hinglish and Devanagari Hindi.** Romanised Hindi / Indian-English
304
+ amount phrases and Devanagari-script Hindi (`डेढ़ लाख`, `सवा करोड़`) are
305
+ both supported, including mixed-script input in the same string.
306
+ Currency and unit detection scan the Latin (`hi_latn`) and Devanagari
307
+ (`hi_deva`) marker lists together. Other Indian languages (Marathi,
308
+ Gujarati, Bengali, Tamil/Telugu/Kannada) are planned via additional
309
+ language packs (the arithmetic core is already language-independent;
310
+ only the class vocabulary and currency-marker lists are per-language) —
311
+ see Roadmap. Devanagari accuracy depends on the bundled weights being
312
+ trained on the `hi_deva` pack; see Devanagari gold-set numbers above.
313
+ - **Offsets are into the normalized string.** `parse()`'s `start`/`end`
314
+ index `normalizeText(text)`, not the raw input, in the rare case NFC
315
+ normalization changes the string's length (see `normalizeText` in the
316
+ API section above).
235
317
  - Text longer than 128 characters is processed with a sliding window
236
318
  (128-char windows, 16-char overlap) and results are merged/deduplicated
237
319
  by span; extremely long inputs may still miss a span that straddles a
@@ -253,7 +335,10 @@ outputs are discarded; only the real characters' predictions are used.
253
335
  (`test/fixtures/parity.jsonl`, `decoded.jsonl` — see
254
336
  `python/README.md`'s "Ship to the npm package" section).
255
337
  - `bench/` — `parse()`/`parseBatch()` latency benchmarks.
256
- - `demo/` — a minimal textarea + live-results HTML demo.
338
+ - `demo/` — an interactive demo: live parse as you type, a per-character
339
+ model-internals view (`inspect()`), batch benchmark controls (CPU vs
340
+ WebGPU), a raw-JSON view of results, a theme toggle, and shareable
341
+ state via URL hash.
257
342
  - `python/sankhya/` — `classes.py` (shared class vocabulary), `core.py`
258
343
  (the deterministic arithmetic core), `langs/` (language packs, e.g.
259
344
  `hi_latn.py`), `noise_latn.py` (typo/spelling-variance injection),
@@ -271,11 +356,12 @@ outputs are discarded; only the real characters' predictions are used.
271
356
  Everything here is scoped to Indian languages — there's no plan to
272
357
  support non-Indian numbering/currency shorthand.
273
358
 
274
- 1. **Devanagari Hindi pack** (डेढ़ लाख). A new language pack plus a new
275
- noise module for Devanagari-specific variance (matra/nukta elision or
276
- substitution) and a charset rebuild no changes needed to `core.ts`/
277
- `core.py` or the runtime, since the arithmetic core and BIO/class
278
- architecture are already language-independent.
359
+ 1. ~~**Devanagari Hindi pack** (डेढ़ लाख).~~ **Done.** The `hi_deva`
360
+ language pack, Devanagari currency markers, Unicode-aware (`\p{L}`/
361
+ `\p{M}`) letters-run repair for matras/nukta/virama, and input
362
+ normalization (NFC + Devanagari-digit mapping) are all in place, and
363
+ mixed Latin/Devanagari input is supported. See `python/README.md` for
364
+ the training-side status and gold-set numbers.
279
365
  2. **Other Indian languages as packs**: Marathi (साडे, सव्वा), Gujarati
280
366
  (સવા, દોઢ), Bengali (দেড়, আড়াই), and Tamil/Telugu/Kannada number
281
367
  words. Same shape as (1) — a new pack, a new noise function, a charset
@@ -293,9 +379,11 @@ npm run bench # parse() and parseBatch() latency
293
379
  npm run size # gzipped dist/index.js size
294
380
  ```
295
381
 
296
- See `demo/index.html` for a minimal textarea + live-results demo that
297
- imports `dist/index.js` directly (no build step needed beyond `npm run
298
- build`).
382
+ See `demo/index.html` for the full interactive demo (live parse,
383
+ per-character model view, benchmark controls, JSON view, theme toggle,
384
+ shareable hash) — it imports `dist/index.js` directly (no build step
385
+ needed beyond `npm run build`). Live at
386
+ https://athrvk.github.io/gpu-sankhya/.
299
387
 
300
388
  ## Releasing
301
389
 
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. */
@@ -8,6 +8,22 @@ export declare function paddedLength(realLen: number): number;
8
8
  /** Upper bound on paddedLength() for any single window (window text is
9
9
  * capped at MAX_LEN chars) -- the size Scratch buffers are allocated to. */
10
10
  export declare const PADDED_MAX: number;
11
+ /** Normalize input text exactly as the Python side does, before char
12
+ * encoding: (1) Unicode NFC normalization, (2) Devanagari digits U+0966-
13
+ * U+096F mapped 1:1 to ASCII "0"-"9", (3) lowercasing. Must stay byte-
14
+ * identical to Python's `s.normalize("NFC")` + digit map + `.lower()`.
15
+ *
16
+ * NFC normalization can change string length (e.g. composing a base +
17
+ * combining mark into fewer code units, or occasionally more). `parse()`
18
+ * returns spans/offsets into `normalizeText(input)`, not the original
19
+ * input string -- for the overwhelming majority of real-world inputs,
20
+ * which already arrive in NFC form, normalization is a no-op on length
21
+ * and offsets, and the `span` field is safe to treat as a substring of
22
+ * the original input too (this is guaranteed to be true when the two
23
+ * strings have equal length). Callers who need to map offsets back onto
24
+ * the original input for non-NFC input should first call
25
+ * `normalizeText()` themselves and index into its result. */
26
+ export declare function normalizeText(s: string): string;
11
27
  export declare function buildCharToId(charset: string[]): Map<string, number>;
12
28
  /** Encode `text` into char ids, right-padded with pad id 0 up to `padLen`
13
29
  * total entries (default: no padding, i.e. exactly text.length). If `out`
package/dist/core.d.ts CHANGED
@@ -11,5 +11,10 @@ export interface LangPack {
11
11
  }
12
12
  type Tok = [string, string];
13
13
  export declare function evaluate(rawTokens: Tok[]): Result;
14
+ /** Merge one or more LangPacks' marker lists into a single pack, de-duped,
15
+ * sorted longest-first so `detectCurrency` tries the longest (most
16
+ * specific) marker before a shorter one that might be its prefix (e.g.
17
+ * "Rs." before "Rs", "रुपये" before a shorter overlapping marker). */
18
+ export declare function mergeLangPacks(...packs: LangPack[]): LangPack;
14
19
  export declare function detectCurrency(text: string, start: number, end: number, pack: LangPack): "INR" | null;
15
20
  export {};
package/dist/index.d.ts CHANGED
@@ -1,6 +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
+ export { normalizeText } from "./charset.js";
5
+ export { CLASSES } from "./classes.js";
4
6
  export interface CreateParserOptions {
5
7
  weights?: WeightsJson;
6
8
  backend?: "cpu" | "webgpu" | "auto";
@@ -16,13 +18,29 @@ export declare class Parser {
16
18
  private clsIdsScratch;
17
19
  private bioProbsScratch;
18
20
  constructor(opts?: CreateParserOptions);
19
- /** Synchronous CPU parse of a single string. */
21
+ /** Synchronous CPU parse of a single string.
22
+ *
23
+ * The returned spans/offsets (`start`, `end`, and `span` when the
24
+ * normalized string's length differs from the input's) are indices into
25
+ * `normalizeText(text)`, not the raw `text` argument -- see
26
+ * normalizeText() in charset.ts. For the overwhelming majority of real
27
+ * input, which already arrives in NFC form, normalization never changes
28
+ * string length, so offsets and `span` are identical either way. */
20
29
  parse(text: string, opts?: ParseOptions): Sankhya[];
21
30
  /** `fw` may cover a padded length (PAD_TAIL right-padding, see charset.ts);
22
31
  * `realLen` (defaults to fw.length, i.e. no padding) bounds decoding to the
23
32
  * actual text -- the padded tail's logits are only used to give the real
24
33
  * tokens correct right-context during the conv stack, never decoded. */
25
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;
26
44
  /** Batched parse. Uses WebGPU when requested/available and the batch is
27
45
  * large enough to be worthwhile; falls back to CPU otherwise. */
28
46
  parseBatch(texts: string[], opts?: ParseOptions): Promise<Sankhya[][]>;
@@ -34,4 +52,8 @@ export declare function parse(text: string, opts?: ParseOptions): Sankhya[];
34
52
  * when `opts.backend === "auto"` and WebGPU is available and the batch is
35
53
  * large (>=32); otherwise runs on CPU. Defaults to CPU. */
36
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;
37
59
  export declare function createParser(opts?: CreateParserOptions): Parser;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- function hA(A){return A.quantized!==void 0}function dA(A){let e=atob(A),n=new Int8Array(e.length);for(let t=0;t<e.length;t++)n[t]=e.charCodeAt(t)<<24>>24;return n}function eA(A){let e=dA(A.data_b64),n=new Float32Array(e.length);for(let t=0;t<e.length;t++)n[t]=e[t]*A.scale;return{shape:A.shape,data:n}}function nA(A){return{shape:A.shape,data:Float32Array.from(A.data)}}function tA(A){let e=A.layers??3,n=A.dilation??2,t=["conv1","conv2","conv3",...e===4?["conv4"]:[]];if(hA(A)){let r={layers:e,dilation:n,charset:A.charset,classes:A.classes,embed:eA(A.embed),conv1:void 0,conv2:void 0,conv3:void 0,bio:void 0,cls:void 0};for(let o of[...t,"bio","cls"]){let u=A[o];r[o]={w:eA(u.w),b:Float32Array.from(u.b)}}return r}let a=A,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 r of[...t,"bio","cls"]){let o=a[r];s[r]={w:nA(o.w),b:Float32Array.from(o.b.data)}}return s}function IA(A){return Math.ceil(A/8)*8}function x(A){return IA(A+16)}var H=x(128);function rA(A){let e=new Map;for(let n=0;n<A.length;n++)e.set(A[n],n);return e}function U(A,e,n,t){let a=A.toLowerCase(),s=e.get("<unk>")??1,r=e.get("<pad>")??0,o=t??a.length,u=n?n.subarray(0,o):new Int32Array(o);for(let f=0;f<a.length;f++)u[f]=e.get(a[f])??s;for(let f=a.length;f<o;f++)u[f]=r;return u}function sA(A){if(A<=128)return[{offset:0,length:A}];let e=[],n=112,t=0;for(;t<A;){let a=Math.min(128,A-t);if(e.push({offset:t,length:a}),t+a>=A)break;t+=n}return e}var O=class{buffers;padded;bioBuf;clsBuf;constructor(e){let n=[e.conv1,e.conv2,e.conv3,...e.layers===4&&e.conv4?[e.conv4]:[]],t=Math.max(e.embed.shape[1],...n.map(s=>s.w.shape[0]));this.buffers=[new Float32Array(t*H),new Float32Array(t*H)];let a=8;this.padded=new Float32Array(t*(H+2*a)),this.bioBuf=new Float32Array(e.bio.w.shape[0]*H),this.clsBuf=new Float32Array(e.cls.w.shape[0]*H)}buf(e){return this.buffers[e%2]}paddedBuf(){return this.padded}};function m(A,e,n,t,a,s,r,o){let[u,f,B]=t.w.shape;if(f!==e)throw new Error(`channel mismatch: expected ${e}, got ${f}`);let w=t.w.data,g=t.b,c=n+2*a;for(let C=0;C<e;C++)o.fill(0,C*c,C*c+a),o.set(A.subarray(C*n,C*n+n),C*c+a),o.fill(0,C*c+a+n,C*c+c);for(let C=0;C<u;C++){let i=C*n,D=g[C],h=C*e*B;if(B===3){for(let P=0;P<n;P++)r[i+P]=D;for(let P=0;P<e;P++){let d=P*c,b=h+P*3,I=w[b],l=w[b+1],v=w[b+2];for(let Q=0;Q<n;Q++){let E=d+Q;r[i+Q]+=I*o[E]+l*o[E+s]+v*o[E+2*s]}}}else if(B===5){for(let P=0;P<n;P++)r[i+P]=D;for(let P=0;P<e;P++){let d=P*c,b=h+P*5,I=w[b],l=w[b+1],v=w[b+2],Q=w[b+3],E=w[b+4];for(let p=0;p<n;p++){let R=d+p;r[i+p]+=I*o[R]+l*o[R+1]+v*o[R+2]+Q*o[R+3]+E*o[R+4]}}}else{for(let P=0;P<n;P++)r[i+P]=D;for(let P=0;P<e;P++){let d=P*c,b=h+P*B;for(let I=0;I<B;I++){let l=w[b+I],v=I*s,Q=d+v;for(let E=0;E<n;E++)r[i+E]+=l*o[Q+E]}}}for(let P=0;P<n;P++){let d=r[i+P];r[i+P]=d>0?d:0}}return u}function oA(A,e,n,t,a){let[s,r]=t.w.shape;if(r!==e)throw new Error(`head channel mismatch: expected ${e}, got ${r}`);let o=t.w.data,u=t.b,f=e-e%4;for(let B=0;B<n;B++){let w=B*s;for(let g=0;g<s;g++){let c=u[g],C=g*e,i=0;for(;i<f;i+=4)c+=o[C+i]*A[i*n+B]+o[C+i+1]*A[(i+1)*n+B]+o[C+i+2]*A[(i+2)*n+B]+o[C+i+3]*A[(i+3)*n+B];for(;i<e;i++)c+=o[C+i]*A[i*n+B];a[w+g]=c}}return s}function j(A,e,n){let t=e.length,a=A.embed,s=a.shape[1],r=n.buf(0);for(let c=0;c<t;c++){let i=e[c]*s;for(let D=0;D<s;D++)r[D*t+c]=a.data[i+D]}let o=s,u=n.paddedBuf(),f=n.buf(1);o=m(r,o,t,A.conv1,1,1,f,u),r=f,f=n.buf(2),o=m(r,o,t,A.conv2,2,1,f,u),r=f;let B=A.dilation,w=Math.floor(B*2/2);if(f=n.buf(3),o=m(r,o,t,A.conv3,w,B,f,u),r=f,A.layers===4&&A.conv4){let C=Math.floor(4);f=n.buf(4),o=m(r,o,t,A.conv4,C,4,f,u),r=f}oA(r,o,t,A.bio,n.bioBuf);let g=oA(r,o,t,A.cls,n.clsBuf);return{bioLogits:n.bioBuf,clsLogits:n.clsBuf,length:t,nCls:g}}function fA(A,e,n,t){let a=-1/0;for(let r=0;r<n;r++)a=Math.max(a,A[e+r]);let s=0;for(let r=0;r<n;r++){let o=Math.exp(A[e+r]-a);t[r]=o,s+=o}for(let r=0;r<n;r++)t[r]/=s;return t}function Y(A,e,n){let t=0,a=-1/0;for(let s=0;s<n;s++){let r=A[e+s];r>a&&(a=r,t=s)}return t}var pA=["PFX_PAAV","PFX_AADHA","PFX_PAUNE","PFX_SAVA","PFX_DEDH","PFX_DHAI","PFX_SAADHE"],RA=Array.from({length:99},(A,e)=>`CARD_${e+1}`),yA=["UNIT_SAU","UNIT_HAZAAR","UNIT_LAKH","UNIT_MILLION","UNIT_CRORE","UNIT_BILLION","UNIT_ARAB","UNIT_KHARAB"],HA=["O","SEP","RANGE","DIGITS","DOT","COMMA"],L=["O",...HA.filter(A=>A!=="O"),...pA,...RA,...yA],M=Object.fromEntries(L.map((A,e)=>[A,e])),aA={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"},K={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 uA(A){return A in K}function BA(A){return A.startsWith("CARD_")}function cA(A){return A in aA}function gA(A){return parseInt(A.split("_",2)[1],10)}function T(A){return aA[A]}var iA=new Set(["SEP","RANGE","DOT","COMMA"]),MA=["PFX_","CARD_","UNIT_"],xA=["PFX_","CARD_","UNIT_"];function FA(A){return MA.some(e=>A.startsWith(e))||A==="DIGITS"}function UA(A){return xA.some(e=>A.startsWith(e))}var mA=M.O,G=M.SEP,W=M.RANGE,OA=M.DIGITS,TA=M.DOT,GA=M.COMMA;function CA(A){return/[a-z]/i.test(A)?"letter":/[0-9]/.test(A)?"digit":/\s/.test(A)?"space":"punct"}function zA(A){let e=[],n=0,t=A.length;for(;n<t;){let a=CA(A[n]),s=n+1;for(;s<t&&CA(A[s])===a;)s++;e.push({type:a,start:n,end:s}),n=s}return e}function kA(A,e,n){let t=new Map;for(let f=e;f<n;f++){let B=A[f];UA(L[B])&&t.set(B,(t.get(B)??0)+1)}if(t.size===0)return mA;let a=-1;for(let f of t.values())f>a&&(a=f);let s=[...t.entries()].filter(([,f])=>f===a).map(([f])=>f);if(s.length===1)return s[0];let r=-1,o=1/0,u=s[0];for(let f of s){let B=0,w=0,g=1/0;for(let c=e;c<n;c++)A[c]===f?(g===1/0&&(g=c),B++,B>w&&(w=B)):B=0;(w>r||w===r&&g<o)&&(r=w,o=g,u=f)}return u}function NA(A,e,n){let t=[],a=e;for(;a<n;){let o=a+1;for(;o<n&&A[o]===A[a];)o++;t.push({start:a,end:o,cls:A[a]}),a=o}let s=kA(A,e,n),r=[];for(let o=0;o<t.length;o++){let u=t[o];if(u.end-u.start>=3){r.push([u.start,u.end,u.cls]);continue}let B=o>0?t[o-1]:null,w=o<t.length-1?t[o+1]:null,g=B!==null&&B.end-B.start>=3,c=w!==null&&w.end-w.start>=3,C;if(g&&c){let i=B.end-B.start;C=w.end-w.start>i?w.cls:B.cls}else g?C=B.cls:c?C=w.cls:C=s;r.push([u.start,u.end,C])}return r}function XA(A,e){let n=A.length,t=new Array(n),a=zA(A);for(let s=0;s<a.length;s++){let r=a[s],{type:o,start:u,end:f}=r;if(o==="digit"){for(let c=u;c<f;c++)t[c]=OA;continue}if(o==="space"){let c=!1;for(let i=u;i<f;i++)if(e[i]===W){c=!0;break}let C=c?W:G;for(let i=u;i<f;i++)t[i]=C;continue}if(o==="letter"){for(let[c,C,i]of NA(e,u,f))for(let D=c;D<C;D++)t[D]=i;continue}let B=s>0?a[s-1].type:null,w=s<a.length-1?a[s+1].type:null,g=G;if(f-u===1){let c=A[u];(c==="."||c===",")&&B==="digit"&&w==="digit"?g=c==="."?TA:GA:(c==="-"||c==="\u2013"||c==="/")&&B==="digit"&&w==="digit"?g=W:g=G}for(let c=u;c<f;c++)t[c]=g}return t}function SA(A,e){let n=Array.from({length:e},(t,a)=>A[a]);for(let t=1;t<e-1;t++)A[t]===0&&(A[t-1]===1||A[t-1]===2)&&A[t+1]===2&&(n[t]=2);return n}function wA(A){return A!==void 0&&A>="0"&&A<="9"}function _A(A,e,n){if(n<=e||!wA(A[n-1]))return n;let t=n;for(;t<A.length&&wA(A[t]);)t++;return t}function PA(A,e,n,t){let a=A.length,s=SA(e,a),r=[],o=null;for(let f=0;f<a;f++){let B=s[f];B===1?(o!==null&&r.push([o,f]),o=f):B===2||o!==null&&(r.push([o,f]),o=null)}o!==null&&r.push([o,a]);for(let f=0;f<r.length;f++)r[f]=[r[f][0],_A(A,r[f][0],r[f][1])];let u=[];for(let[f,B]of r){let w=A.slice(f,B),g=Array.from({length:B-f},(l,v)=>n[f+v]),c=XA(w,g),C=f,i=[];for(let l=f+1;l<=B;l++)(l===B||c[l-f]!==c[C-f])&&(i.push([c[C-f],C,l]),C=l);let D=0,h=i.length;for(;D<h&&iA.has(L[i[D][0]]);)D++;for(;h>D&&iA.has(L[i[h-1][0]]);)h--;let P=i.slice(D,h);if(P.length===0)continue;let d=P[0][1],b=P[P.length-1][2];if(!P.some(([l])=>FA(L[l])))continue;let I=null;if(t){let l=[];for(let v=d;v<b;v++)l.push(Math.max(...t[v]));if(I=l.length?l.reduce((v,Q)=>v+Q,0)/l.length:0,I<.5)continue}u.push({start:d,end:b,text:A.slice(d,b),tokens:P.map(([l,v,Q])=>[l,A.slice(v,Q)]),confidence:I})}return u}function jA(A){let e=[],n="",t=!1,a=()=>{if(t){let s=n.replace(/,/g,""),r=parseFloat(s);e.push(["NUM",Number.isNaN(r)?0:r])}n="",t=!1};for(let[s,r]of A)s!=="SEP"&&(s==="DIGITS"||s==="DOT"||s==="COMMA"?(n+=r,t=!0):(a(),e.push([s,r])));return a(),e}function YA(A,e){if(e!==null){let n=K[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 JA(A){let e=jA(A),n=0,t=null,a=null,s=null,r=null;function o(u){let f=YA(s,r);if(u===null)n+=f*1;else{let B=T(u);t!==null&&B>t?n=n*B:n=n+f*B,t=B,(a===null||B>T(a))&&(a=u)}s=null,r=null}for(let[u,f]of e)if(u==="NUM")s!==null&&o(null),s=f;else if(BA(u)){s!==null&&o(null);try{s=gA(u)}catch{}}else if(uA(u))r!==null&&o(null),r=u;else if(cA(u))o(u);else continue;return(s!==null||r!==null)&&o(null),[n,a]}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 KA(A){let e=[],n=0;for(;n<A.length;){let[t,a]=A[n];if(t.startsWith("PFX_")){let s=a,r=n+1;for(;;){let o=r;if(o<A.length&&A[o][0]==="SEP"&&o++,o<A.length&&A[o][0]===t){for(let u=r;u<=o;u++)s+=A[u][1];r=o+1;continue}break}e.push([t,s]),n=r}else e.push(A[n]),n++}return e}function DA(A){try{let e=A.map(g=>g[0]),n=KA(A),t=[[]];for(let[g,c]of n){if(g==="RANGE"){t.length<2&&t.push([]);continue}t[t.length-1].push([g,c])}let a=t.filter(g=>g.length>0).map(g=>JA(g));if(a.length===0)return{value:0,range:null,unit:null,classes:e,currency:null};if(a.length===1){let[g,c]=a[0];return{value:z(g),range:null,unit:c?J[c]??null:null,classes:e,currency:null}}let[s,r]=a[0],[o,u]=a[1],f;r===null&&u!==null?(s=s*T(u),f=u):f=r!==null?r:u;let[B,w]=s<=o?[s,o]:[o,s];return{value:z(B),range:[z(B),z(w)],unit:f?J[f]??null:null,classes:e,currency:null}}catch{return{value:0,range:null,unit:null,classes:A.map(e=>e[0]),currency:null}}}function vA(A,e,n,t){let a=A.slice(Math.max(0,e-4),e),s=A.slice(n,n+6),r=a.replace(/\s+$/,"");for(let u of t.currency_markers_before??[]){let f=u.replace(/\.+$/,"").toLowerCase(),B=r.toLowerCase();if(B.endsWith(u.toLowerCase())||B.endsWith(f))return"INR"}let o=s.replace(/^\s+/,"");for(let u of t.currency_words_after??[]){let f=u.toLowerCase();if(o.toLowerCase().startsWith(f))return"INR"}return null}var lA={currency_markers_before:["\u20B9","Rs","Rs.","rs","INR","Re"],currency_words_after:["rupaye","rupay","rupees","rupiya","rupya","/-"]};var WA=`
1
+ function LA(A){return A.version===2&&Array.isArray(A.conv)}function dA(A){return A.quantized!==void 0}function FA(A){let B=atob(A),n=new Int8Array(B.length);for(let e=0;e<B.length;e++)n[e]=B.charCodeAt(e)<<24>>24;return n}function T(A){let B=FA(A.data_b64),n=new Float32Array(B.length);for(let e=0;e<B.length;e++)n[e]=B[e]*A.scale;return{shape:A.shape,data:n}}function U(A){return{shape:A.shape,data:Float32Array.from(A.data)}}function tA(A,B){return A*(B-1)/2}function Y(A){return{w:U(A.w),b:Float32Array.from(A.b.data)}}function m(A){return{w:T(A.w),b:Float32Array.from(A.b)}}function gA(A){let B=dA(A);if(LA(A)){let g=A.conv.map(f=>{let w=tA(f.dilation,f.k);if(B){let P=f;return{k:f.k,dilation:f.dilation,residual:f.residual,padding:w,w:T(P.w),b:Float32Array.from(P.b)}}let s=f;return{k:f.k,dilation:f.dilation,residual:f.residual,padding:w,w:U(s.w),b:Float32Array.from(s.b.data)}});return{version:2,charset:A.charset,classes:A.classes,embed:B?T(A.embed):U(A.embed),conv:g,bio:B?m(A.bio):Y(A.bio),cls:B?m(A.cls):Y(A.cls)}}let n=A.layers??3,e=A.dilation??2,t=[{name:"conv1",k:3,dilation:1},{name:"conv2",k:5,dilation:1},{name:"conv3",k:3,dilation:e}];n===4&&t.push({name:"conv4",k:3,dilation:4});let r=t.map(g=>{let f=tA(g.dilation,g.k);if(B){let u=A[g.name];if(!u)throw new Error(`missing ${g.name} in weights JSON`);return{k:g.k,dilation:g.dilation,residual:!1,padding:f,w:T(u.w),b:Float32Array.from(u.b)}}let s=A[g.name];if(!s)throw new Error(`missing ${g.name} in weights JSON`);return{k:g.k,dilation:g.dilation,residual:!1,padding:f,w:U(s.w),b:Float32Array.from(s.b.data)}});return{version:A.version??1,charset:A.charset,classes:A.classes,embed:B?T(A.embed):U(A.embed),conv:r,bio:B?m(A.bio):Y(A.bio),cls:B?m(A.cls):Y(A.cls)}}function MA(A){return Math.ceil(A/8)*8}function x(A){return MA(A+24)}var R=x(128),RA=/[०-९]/g;function k(A){return A.normalize("NFC").replace(RA,B=>String(B.charCodeAt(0)-2406)).toLowerCase()}function sA(A){let B=new Map;for(let n=0;n<A.length;n++)B.set(A[n],n);return B}function p(A,B,n,e){let t=B.get("<unk>")??1,r=B.get("<pad>")??0,g=e??A.length,f=n?n.subarray(0,g):new Int32Array(g);for(let w=0;w<A.length;w++)f[w]=B.get(A[w])??t;for(let w=A.length;w<g;w++)f[w]=r;return f}function Z(A){if(A<=128)return[{offset:0,length:A}];let B=[],n=112,e=0;for(;e<A;){let t=Math.min(128,A-e);if(B.push({offset:e,length:t}),e+t>=A)break;e+=n}return B}var X=class{buffers;padded;bioBuf;clsBuf;constructor(B){let n=B.conv,e=Math.max(B.embed.shape[1],...n.map(r=>r.w.shape[0]));this.buffers=[new Float32Array(e*R),new Float32Array(e*R)];let t=n.length?Math.max(...n.map(r=>r.padding)):0;this.padded=new Float32Array(e*(R+2*t)),this.bioBuf=new Float32Array(B.bio.w.shape[0]*R),this.clsBuf=new Float32Array(B.cls.w.shape[0]*R)}buf(B){return this.buffers[B%2]}paddedBuf(){return this.padded}};function OA(A,B,n,e,t,r){let[g,f,w]=e.w.shape;if(f!==B)throw new Error(`channel mismatch: expected ${B}, got ${f}`);let s=e.w.data,P=e.b,u=e.padding,o=e.dilation,C=n+2*u;for(let D=0;D<B;D++)r.fill(0,D*C,D*C+u),r.set(A.subarray(D*n,D*n+n),D*C+u),r.fill(0,D*C+u+n,D*C+C);for(let D=0;D<g;D++){let Q=D*n,i=P[D],I=D*B*w;if(w===3){for(let v=0;v<n;v++)t[Q+v]=i;for(let v=0;v<B;v++){let h=v*C,b=I+v*3,L=s[b],H=s[b+1],E=s[b+2];for(let c=0;c<n;c++){let a=h+c;t[Q+c]+=L*r[a]+H*r[a+o]+E*r[a+2*o]}}}else if(w===5){for(let v=0;v<n;v++)t[Q+v]=i;for(let v=0;v<B;v++){let h=v*C,b=I+v*5,L=s[b],H=s[b+1],E=s[b+2],c=s[b+3],a=s[b+4];for(let d=0;d<n;d++){let F=h+d;t[Q+d]+=L*r[F]+H*r[F+1]+E*r[F+2]+c*r[F+3]+a*r[F+4]}}}else{for(let v=0;v<n;v++)t[Q+v]=i;for(let v=0;v<B;v++){let h=v*C,b=I+v*w;for(let L=0;L<w;L++){let H=s[b+L],E=L*o,c=h+E;for(let a=0;a<n;a++)t[Q+a]+=H*r[c+a]}}}if(e.residual)for(let v=0;v<n;v++){let h=t[Q+v];t[Q+v]=(h>0?h:0)+A[Q+v]}else for(let v=0;v<n;v++){let h=t[Q+v];t[Q+v]=h>0?h:0}}return g}function wA(A,B,n,e,t){let[r,g]=e.w.shape;if(g!==B)throw new Error(`head channel mismatch: expected ${B}, got ${g}`);let f=e.w.data,w=e.b,s=B-B%4;for(let P=0;P<n;P++){let u=P*r;for(let o=0;o<r;o++){let C=w[o],D=o*B,Q=0;for(;Q<s;Q+=4)C+=f[D+Q]*A[Q*n+P]+f[D+Q+1]*A[(Q+1)*n+P]+f[D+Q+2]*A[(Q+2)*n+P]+f[D+Q+3]*A[(Q+3)*n+P];for(;Q<B;Q++)C+=f[D+Q]*A[Q*n+P];t[u+o]=C}}return r}function j(A,B,n){let e=B.length,t=A.embed,r=t.shape[1],g=n.buf(0);for(let u=0;u<e;u++){let C=B[u]*r;for(let D=0;D<r;D++)g[D*e+u]=t.data[C+D]}let f=r,w=n.paddedBuf(),s=1;for(let u of A.conv){let o=n.buf(s);f=OA(g,f,e,u,o,w),g=o,s++}wA(g,f,e,A.bio,n.bioBuf);let P=wA(g,f,e,A.cls,n.clsBuf);return{bioLogits:n.bioBuf,clsLogits:n.clsBuf,length:e,nCls:P}}function $(A,B,n,e){let t=-1/0;for(let g=0;g<n;g++)t=Math.max(t,A[B+g]);let r=0;for(let g=0;g<n;g++){let f=Math.exp(A[B+g]-t);e[g]=f,r+=f}for(let g=0;g<n;g++)e[g]/=r;return e}function G(A,B,n){let e=0,t=-1/0;for(let r=0;r<n;r++){let g=A[B+r];g>t&&(t=g,e=r)}return e}var xA=["PFX_PAAV","PFX_AADHA","PFX_PAUNE","PFX_SAVA","PFX_DEDH","PFX_DHAI","PFX_SAADHE"],zA=Array.from({length:99},(A,B)=>`CARD_${B+1}`),TA=["UNIT_SAU","UNIT_HAZAAR","UNIT_LAKH","UNIT_MILLION","UNIT_CRORE","UNIT_BILLION","UNIT_ARAB","UNIT_KHARAB"],UA=["O","SEP","RANGE","DIGITS","DOT","COMMA"],M=["O",...UA.filter(A=>A!=="O"),...xA,...zA,...TA],O=Object.fromEntries(M.map((A,B)=>[A,B])),PA={UNIT_SAU:100,UNIT_HAZAAR:1e3,UNIT_LAKH:1e5,UNIT_MILLION:1e6,UNIT_CRORE:1e7,UNIT_BILLION:1e9,UNIT_ARAB:1e9,UNIT_KHARAB:1e11},AA={UNIT_SAU:"sau",UNIT_HAZAAR:"hazaar",UNIT_LAKH:"lakh",UNIT_MILLION:"million",UNIT_CRORE:"crore",UNIT_BILLION:"billion",UNIT_ARAB:"arab",UNIT_KHARAB:"kharab"},BA={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 BA}function oA(A){return A.startsWith("CARD_")}function vA(A){return A in PA}function DA(A){return parseInt(A.split("_",2)[1],10)}function N(A){return PA[A]}var QA=new Set(["SEP","RANGE","DOT","COMMA"]),pA=["PFX_","CARD_","UNIT_"],GA=["PFX_","CARD_","UNIT_"];function yA(A){return pA.some(B=>A.startsWith(B))||A==="DIGITS"}function YA(A){return GA.some(B=>A.startsWith(B))}var mA=O.O,J=O.SEP,eA=O.RANGE,XA=O.DIGITS,jA=O.DOT,NA=O.COMMA,JA=/\p{L}|\p{M}/u;function uA(A){return JA.test(A)?"letter":/[0-9]/.test(A)?"digit":/\s/.test(A)?"space":"punct"}function SA(A){let B=[],n=0,e=A.length;for(;n<e;){let t=uA(A[n]),r=n+1;for(;r<e&&uA(A[r])===t;)r++;B.push({type:t,start:n,end:r}),n=r}return B}function KA(A,B,n){let e=new Map;for(let s=B;s<n;s++){let P=A[s];YA(M[P])&&e.set(P,(e.get(P)??0)+1)}if(e.size===0)return mA;let t=-1;for(let s of e.values())s>t&&(t=s);let r=[...e.entries()].filter(([,s])=>s===t).map(([s])=>s);if(r.length===1)return r[0];let g=-1,f=1/0,w=r[0];for(let s of r){let P=0,u=0,o=1/0;for(let C=B;C<n;C++)A[C]===s?(o===1/0&&(o=C),P++,P>u&&(u=P)):P=0;(u>g||u===g&&o<f)&&(g=u,f=o,w=s)}return w}function _A(A,B,n){let e=[],t=B;for(;t<n;){let f=t+1;for(;f<n&&A[f]===A[t];)f++;e.push({start:t,end:f,cls:A[t]}),t=f}let r=KA(A,B,n),g=[];for(let f=0;f<e.length;f++){let w=e[f];if(w.end-w.start>=3){g.push([w.start,w.end,w.cls]);continue}let P=f>0?e[f-1]:null,u=f<e.length-1?e[f+1]:null,o=P!==null&&P.end-P.start>=3,C=u!==null&&u.end-u.start>=3,D;if(o&&C){let Q=P.end-P.start;D=u.end-u.start>Q?u.cls:P.cls}else o?D=P.cls:C?D=u.cls:D=r;g.push([w.start,w.end,D])}return g}function WA(A,B){let n=A.length,e=new Array(n),t=SA(A);for(let r=0;r<t.length;r++){let g=t[r],{type:f,start:w,end:s}=g;if(f==="digit"){for(let C=w;C<s;C++)e[C]=XA;continue}if(f==="space"){let C=!1;for(let Q=w;Q<s;Q++)if(B[Q]===eA){C=!0;break}let D=C?eA:J;for(let Q=w;Q<s;Q++)e[Q]=D;continue}if(f==="letter"){for(let[C,D,Q]of _A(B,w,s))for(let i=C;i<D;i++)e[i]=Q;continue}let P=r>0?t[r-1].type:null,u=r<t.length-1?t[r+1].type:null,o=J;if(s-w===1){let C=A[w];(C==="."||C===",")&&P==="digit"&&u==="digit"?o=C==="."?jA:NA:(C==="-"||C==="\u2013"||C==="/")&&P==="digit"&&u==="digit"?o=eA:o=J}for(let C=w;C<s;C++)e[C]=o}return e}function VA(A,B){let n=Array.from({length:B},(e,t)=>A[t]);for(let e=1;e<B-1;e++)A[e]===0&&(A[e-1]===1||A[e-1]===2)&&A[e+1]===2&&(n[e]=2);return n}function EA(A){return A!==void 0&&A>="0"&&A<="9"}function qA(A,B,n){if(n<=B||!EA(A[n-1]))return n;let e=n;for(;e<A.length&&EA(A[e]);)e++;return e}function cA(A,B,n,e){let t=A.length,r=VA(B,t),g=[],f=null;for(let s=0;s<t;s++){let P=r[s];P===1?(f!==null&&g.push([f,s]),f=s):P===2||f!==null&&(g.push([f,s]),f=null)}f!==null&&g.push([f,t]);for(let s=0;s<g.length;s++)g[s]=[g[s][0],qA(A,g[s][0],g[s][1])];let w=[];for(let[s,P]of g){let u=A.slice(s,P),o=Array.from({length:P-s},(H,E)=>n[s+E]),C=WA(u,o),D=s,Q=[];for(let H=s+1;H<=P;H++)(H===P||C[H-s]!==C[D-s])&&(Q.push([C[D-s],D,H]),D=H);let i=0,I=Q.length;for(;i<I&&QA.has(M[Q[i][0]]);)i++;for(;I>i&&QA.has(M[Q[I-1][0]]);)I--;let v=Q.slice(i,I);if(v.length===0)continue;let h=v[0][1],b=v[v.length-1][2];if(!v.some(([H])=>yA(M[H])))continue;let L=null;if(e){let H=[];for(let E=h;E<b;E++)H.push(Math.max(...e[E]));if(L=H.length?H.reduce((E,c)=>E+c,0)/H.length:0,L<.5)continue}w.push({start:h,end:b,text:A.slice(h,b),tokens:v.map(([H,E,c])=>[H,A.slice(E,c)]),confidence:L})}return w}function ZA(A){let B=[],n="",e=!1,t=()=>{if(e){let r=n.replace(/,/g,""),g=parseFloat(r);B.push(["NUM",Number.isNaN(g)?0:g])}n="",e=!1};for(let[r,g]of A)r!=="SEP"&&(r==="DIGITS"||r==="DOT"||r==="COMMA"?(n+=g,e=!0):(t(),B.push([r,g])));return t(),B}function $A(A,B){if(B!==null){let n=BA[B];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 AB(A){let B=ZA(A),n=0,e=null,t=null,r=null,g=null;function f(w){let s=$A(r,g);if(w===null)n+=s*1;else{let P=N(w);e!==null&&P>e?n=n*P:n=n+s*P,e=P,(t===null||P>N(t))&&(t=w)}r=null,g=null}for(let[w,s]of B)if(w==="NUM")r!==null&&f(null),r=s;else if(oA(w)){r!==null&&f(null);try{r=DA(w)}catch{}}else if(CA(w))g!==null&&f(null),g=w;else if(vA(w))f(w);else continue;return(r!==null||g!==null)&&f(null),[n,t]}function S(A){let B=Math.round(A),n=Math.max(1e-6,Math.abs(A)*1e-9);return Math.abs(A-B)<n?B:Math.round(A*1e6)/1e6}function BB(A){let B=[],n=0;for(;n<A.length;){let[e,t]=A[n];if(e.startsWith("PFX_")){let r=t,g=n+1;for(;;){let f=g;if(f<A.length&&A[f][0]==="SEP"&&f++,f<A.length&&A[f][0]===e){for(let w=g;w<=f;w++)r+=A[w][1];g=f+1;continue}break}B.push([e,r]),n=g}else B.push(A[n]),n++}return B}function aA(A){try{let B=A.map(o=>o[0]),n=BB(A),e=[[]];for(let[o,C]of n){if(o==="RANGE"){e.length<2&&e.push([]);continue}e[e.length-1].push([o,C])}let t=e.filter(o=>o.length>0).map(o=>AB(o));if(t.length===0)return{value:0,range:null,unit:null,classes:B,currency:null};if(t.length===1){let[o,C]=t[0];return{value:S(o),range:null,unit:C?AA[C]??null:null,classes:B,currency:null}}let[r,g]=t[0],[f,w]=t[1],s;g===null&&w!==null?(r=r*N(w),s=w):s=g!==null?g:w;let[P,u]=r<=f?[r,f]:[f,r];return{value:S(P),range:[S(P),S(u)],unit:s?AA[s]??null:null,classes:B,currency:null}}catch{return{value:0,range:null,unit:null,classes:A.map(B=>B[0]),currency:null}}}function iA(...A){let B=(e,t)=>t.length-e.length,n=e=>[...new Set(e.flat())].sort(B);return{currency_markers_before:n(A.map(e=>e.currency_markers_before??[])),currency_words_after:n(A.map(e=>e.currency_words_after??[]))}}function IA(A,B,n,e){let t=A.slice(Math.max(0,B-4),B),r=A.slice(n,n+6),f=t.replace(/\s+$/,"").toLowerCase(),w=[...e.currency_markers_before??[]].sort((o,C)=>C.length-o.length);for(let o of w){let C=o.replace(/\.+$/,"").toLowerCase();if(f.endsWith(o.toLowerCase())||f.endsWith(C))return"INR"}let P=r.replace(/^\s+/,"").toLowerCase(),u=[...e.currency_words_after??[]].sort((o,C)=>C.length-o.length);for(let o of u){let C=o.toLowerCase();if(P.startsWith(C))return"INR"}return null}var HA={currency_markers_before:["\u20B9","Rs","Rs.","rs","INR","Re"],currency_words_after:["rupaye","rupay","rupees","rupiya","rupya","/-"]};var bA={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 eB=`
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
- `,VA=`
21
- struct Params { batch: u32, length: u32, cIn: u32, cOut: u32, k: u32, padding: u32, dilation: u32, relu: u32, stride: u32 };
20
+ `,nB=`
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
- `,qA=`
55
+ `,rB=`
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 V(){return typeof navigator<"u"&&!!navigator.gpu}var k=null;function q(){return k||(k=(async()=>{if(!V())return!1;try{return await navigator.gpu.requestAdapter()!==null}catch{return!1}})(),k)}var N=class{weights;state=null;constructor(e){this.weights=e}async init(){if(this.state)return this.state;if(!V())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(),t=(u,f)=>{let B=n.createBuffer({size:Math.max(4,u.byteLength),usage:f,mappedAtCreation:!0});return new Float32Array(B.getMappedRange()).set(u),B.unmap(),B},a=GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,s=this.weights,o=[s.conv1,s.conv2,s.conv3,...s.layers===4&&s.conv4?[s.conv4]:[]].map(u=>({w:t(u.w.data,a),b:t(u.b,a)}));return this.state={device:n,embedModule:n.createShaderModule({code:WA}),convModule:n.createShaderModule({code:VA}),headModule:n.createShaderModule({code:qA}),embedBuf:t(s.embed.data,a),convBufs:o,bioBuf:{w:t(s.bio.w.data,a),b:t(s.bio.b,a)},clsBuf:{w:t(s.cls.w.data,a),b:t(s.cls.b,a)}},this.state}async run(e,n,t){let a=await this.init(),{device:s}=a,r=this.weights,o=r.embed.shape[1],u=GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC,f=GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,B=s.createBuffer({size:e.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,mappedAtCreation:!0});new Int32Array(B.getMappedRange()).set(e),B.unmap();let w=v=>{let Q=s.createBuffer({size:v.byteLength,usage:f,mappedAtCreation:!0});return new Uint32Array(Q.getMappedRange()).set(v),Q.unmap(),Q},g=s.limits?.maxComputeWorkgroupsPerDimension??65535,c=v=>{let Q=Math.max(1,Math.ceil(v/64)),E=Math.min(Q,g),p=Math.ceil(Q/E);return{x:E,y:p,stride:E*64}},C=(v,Q,E)=>{let p=s.createBindGroup({layout:v.getBindGroupLayout(0),entries:Q}),R=s.createCommandEncoder(),y=R.beginComputePass();y.setPipeline(v),y.setBindGroup(0,p),y.dispatchWorkgroups(E.x,E.y),y.end(),s.queue.submit([R.finish()])},i=s.createBuffer({size:n*o*t*4,usage:u});{let v=c(n*t),Q=w(new Uint32Array([n,t,o,r.embed.shape[0],v.stride])),E=s.createComputePipeline({layout:"auto",compute:{module:a.embedModule,entryPoint:"main"}});C(E,[{binding:0,resource:{buffer:Q}},{binding:1,resource:{buffer:B}},{binding:2,resource:{buffer:a.embedBuf}},{binding:3,resource:{buffer:i}}],v)}let D=o,h=[r.conv1,r.conv2,r.conv3,...r.layers===4&&r.conv4?[r.conv4]:[]],P=s.createComputePipeline({layout:"auto",compute:{module:a.convModule,entryPoint:"main"}});for(let v=0;v<h.length;v++){let Q=h[v],[E,,p]=Q.w.shape,R=v===2,y=v===3,F=y?4:R?r.dilation:1,_=y?Math.floor(8/2):R?Math.floor(r.dilation*2/2):v===0?1:2,$=s.createBuffer({size:n*E*t*4,usage:u}),AA=c(n*E*t),bA=w(new Uint32Array([n,t,D,E,p,_,F,1,AA.stride]));C(P,[{binding:0,resource:{buffer:bA}},{binding:1,resource:{buffer:i}},{binding:2,resource:{buffer:a.convBufs[v].w}},{binding:3,resource:{buffer:a.convBufs[v].b}},{binding:4,resource:{buffer:$}}],AA),i=$,D=E}let d=s.createComputePipeline({layout:"auto",compute:{module:a.headModule,entryPoint:"main"}}),b=async(v,Q)=>{let E=s.createBuffer({size:n*t*Q*4,usage:u}),p=c(n*t*Q),R=w(new Uint32Array([n,t,D,Q,p.stride]));C(d,[{binding:0,resource:{buffer:R}},{binding:1,resource:{buffer:i}},{binding:2,resource:{buffer:v.w}},{binding:3,resource:{buffer:v.b}},{binding:4,resource:{buffer:E}}],p);let y=s.createBuffer({size:n*t*Q*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ}),F=s.createCommandEncoder();F.copyBufferToBuffer(E,0,y,0,n*t*Q*4),s.queue.submit([F.finish()]),await y.mapAsync(GPUMapMode.READ);let _=new Float32Array(y.getMappedRange().slice(0));return y.unmap(),_},I=await b(a.bioBuf,r.bio.w.shape[0]),l=await b(a.clsBuf,r.cls.w.shape[0]);return{bio:I,cls:l}}};var QA={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","~","\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:[56,16],scale:.03634775057435036,data_b64:"AAAAAAAAAAAAAAAAAAAAAAfSJgP/6wYvDdn2DikdGePzEOgLCAYRAv4YAwMPRtO3+B4L/v76H//xITRCCwv3ufAZHyPXR/MJ0/Hz8uMf/Bb9E+kAF/UdCvk/zP/j5gEULdsJDrjR+ggHAgkNDegV5/q9/v8aCuf+7/M19QMgGSbo9OoQEQ024/4D8N795PcH+QMHIAgL+v0F68wE7QkECzLh8w3F/hoy5PAz8M3u/NIVBtr3ACEM/+wSXSX9G9Pn8i4T/RwKBRTmAAfy+jXmmQju+TPcH+elFEcKACYa2Pv8PxjxKADx6wAK/fbuEvub3+QiGj0HBMMTNBTL6uo9+uEfFSYD6e3y/kcb1wHmNgnoFhknDfTZ3vs4ENED4jL/+CUfJx3+6uUPPAfOAOcy/P8aHisc+uDnDjv+yA7uMQL2ICAwJff81g46E9AC4jP3+RoWJiH77eUUOwfJ/uk4AvwgIyoo/fXFDzEX0f7jMPb0HyApJPTq2A85Dsz57DD69BkdHxX89d4aPA7MBOs9/OP+Bucw7yfyFfkSJQIbIQ/6IQcYAAYlEOMKIE4qIfK4PiLzDCUM8vsIAwrrBvkr+ekCJOpI8O4l/PgZI/8Y/ycE3AT6DfwG3twb4S4BkDCe8er/veoxIMjwHQzU7RLoHxYEyuHz3soM/wvTtwPTLMfx6ekfC/8U3u8O2xgUDv8l2Abmn/Xq+OcfDX/dQhQSDwkR/enVzO0SFBHkAO43Aw8a/SUZ8CjlGP7s9tQMLxEA7v7V8AwJ+xQBAOq92PsBGAjmKxHw99oZ8UwpGeQlzjfv5g7s2yHhKOb7/fU58t8U9ODx4Pc6Jwjl+cASCQEy6AXp983MLhoQOCPhPuQVKBHmTuUb5xg2AvryHe0K0AwUGhzk1AEYyQnmJQsV4uAUFBcgCNoh4w/01xLTCEi3AA/yEPft4+X69PUXBwn56gYeGeXiEurfHxm4EiT1Be4w/AkWHvTv5CnH2frpD/YxLAO2DBwc7B/iAOK/+fvnGhD4GPshBisW1N/kEfsN/cLd+Af55AMmHMO9Ce08+vogAR/54NsMFCShxvoDVhPxJPgT8tMACeMTA84NMPEn0hHyNdgA/+oG5PsoD/vky97z7wPx+C8V6AHH+elF8hjpCNEVYdn97Oc8Fv3xA/EI5QAaFwJCyCzYHS8ECOgN+PEF5Ns="},conv1:{w:{shape:[32,16,3],scale:.006139184348285198,data_b64:"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"},b:[.45622,.23405,.22881,.099713,.22726,.17001,.048671,-.17105,.11404,.33485,.15626,-.46358,-.013018,.099381,-.010189,.020385,-.14867,-.17133,-.030829,.10267,-.13208,-.38272,.064075,-.042051,-.15628,.20139,.15375,-.013163,.098084,.047966,.22716,-.074847]},conv2:{w:{shape:[32,32,5],scale:.009565402753651142,data_b64:"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"},b:[.25476,.026761,.091159,.2577,.011283,-.31972,.73302,-.021524,-.20232,.049772,-.091728,.11994,-.40917,.061952,-.055094,-34595e-9,.1525,.17977,.025422,.47911,.2569,-.067177,.086829,-.011742,.12641,.13773,.33299,-.2564,-.067883,.021229,.84651,.89692]},conv3:{w:{shape:[32,32,3],scale:.011997192166745663,data_b64:"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"},b:[.95696,.38779,-.019267,.15136,1.357,.8184,.18205,.47105,.10438,.032386,-.26726,1.2156,.86512,-.053118,.57925,-.21673,1.2695,.64724,.11427,.29962,.64951,-.061881,.019131,.1549,1.2697,.042946,.61255,-.57353,-.13114,1.0174,.11395,.26929]},conv4:{w:{shape:[32,32,3],scale:.01576780155301094,data_b64:"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"},b:[.89296,.26698,.91654,.46187,-.081608,-.53949,.55512,.21752,1.0169,.47651,.34679,.29588,1.5106,.60742,-.1133,-.028405,.037585,-.23182,1.2854,.27839,.24252,.69016,-.17436,.5821,-.059923,.050272,1.2284,.32915,.25613,.31951,.25337,.76967]},bio:{w:{shape:[3,32],scale:.008006345480680466,data_b64:"/QLWCQR//MgHBaD4EfoD8/ryCAcCAgLuCwQV9wcD+frzA/sGEyMXffcE/vwF/gH2/vf0CAH7D/YJCAj/Cgf9+u8DNwfmtyEF6AZeA/3/B/YA9+gK/vQM9QgI/gILCf36"},b:[.87751,-.81366,-.26467]},cls:{w:{shape:[120,32],scale:.009712129831314087,data_b64:"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"},b:[1.5043,.16996,-.14971,.29736,-.50758,.11862,.029212,.1628,-.14132,-.091054,-.60198,-.25317,-.13608,.068661,-.12722,-.36333,-.16175,-.27111,-.14709,-.23161,.064164,-.46374,-.52342,-.047273,-.12203,-.25037,-.5412,-.33762,-.01589,-.37118,.019277,-.44845,-.27225,-.70827,-.15251,-.32633,-.4003,-.38486,-.18858,-.20396,-.32059,-.34326,-.50492,-.42893,-.53269,-.39711,-.1355,-.26617,-.36554,-.46165,-.1886,-.22946,-.20626,-.3812,-.17224,-.22552,-.30371,-.17449,-.087149,-.33845,-.4778,-.21339,-.29264,-.56332,-.28292,-.33691,-.48023,-.25778,-.27241,-.39297,-.31795,-.44322,-.24301,-.22345,-.32524,.084856,-.17181,-.34565,-.19354,-.13021,.0022854,-.58743,.034923,-.45897,-.51305,-.31592,-.3854,-.37011,-.19354,-.46266,-.29652,-.21346,-.17185,-.48329,-.49975,-.41428,-.45629,-.16367,-.29652,-.48026,-.54081,-.55343,-.46746,-.3885,-.29678,-.45206,-.37856,-.124,-.061739,.043541,-.046948,-.14789,-.36611,.21359,.29946,-.6239,.19281,-.41082,-.34077,-.22366]}};var S=class{weights;charToId;gpu=null;defaultBackend;scratch;idsScratch=new Int32Array(H);bioIdsScratch=new Int32Array(128);clsIdsScratch=new Int32Array(128);bioProbsScratch=Array.from({length:128},()=>new Float32Array(3));constructor(e={}){this.weights=tA(e.weights??QA),this.charToId=rA(this.weights.charset),this.defaultBackend=e.backend??"cpu",this.scratch=new O(this.weights)}parse(e,n={}){let t=sA(e.length);if(t.length===1&&t[0].length===e.length){let r=x(e.length),o=U(e,this.charToId,this.idsScratch,r),u=j(this.weights,o,this.scratch);return this.decodeForward(e,u,0,e.length)}let a=[],s=new Set;for(let r of t){let o=e.slice(r.offset,r.offset+r.length),u=x(o.length),f=U(o,this.charToId,this.idsScratch,u),B=j(this.weights,f,this.scratch),w=this.decodeForward(o,B,r.offset,o.length);for(let g of w){let c=`${g.start}:${g.end}`;s.has(c)||(s.add(c),a.push(g))}}return a.sort((r,o)=>r.start-o.start),a}decodeForward(e,n,t,a=n.length){let s=a,r=s<=128,o=r?this.bioIdsScratch:new Int32Array(s),u=r?this.clsIdsScratch:new Int32Array(s),f=r?this.bioProbsScratch:Array.from({length:s},()=>new Float32Array(3));for(let g=0;g<s;g++)o[g]=Y(n.bioLogits,g*3,3),u[g]=Y(n.clsLogits,g*n.nCls,n.nCls),fA(n.bioLogits,g*3,3,f[g]);let B=PA(e,o.subarray(0,s),u.subarray(0,s),f),w=[];for(let g of B){let c=g.tokens.map(([D,h])=>[L[D],h]),C=DA(c),i=vA(e,g.start,g.end,lA);w.push({span:g.text,start:g.start+t,end:g.end+t,value:C.value,...C.range?{range:C.range}:{},unit:C.unit??null,currency:i,confidence:g.confidence??0,classes:C.classes})}return w}async parseBatch(e,n={}){let t=n.backend??this.defaultBackend;if(!(t==="webgpu"||t==="auto"&&e.length>=32&&await q()))return e.map(u=>this.parse(u,{backend:"cpu"}));let s=new Array(e.length),r=[],o=[];for(let u=0;u<e.length;u++)e[u].length<=128?r.push(u):o.push(u);for(let u of o)s[u]=this.parse(e[u],{backend:"cpu"});if(r.length>0){this.gpu||(this.gpu=new N(this.weights));let u=Math.max(...r.map(D=>e[D].length),1),f=x(u),B=r.length,w=new Int32Array(B*f),g=this.charToId.get("<pad>")??0;w.fill(g);for(let D=0;D<B;D++){let h=e[r[D]],P=U(h,this.charToId);w.set(P,D*f)}let{bio:c,cls:C}=await this.gpu.run(w,B,f),i=this.weights.cls.w.shape[0];for(let D=0;D<B;D++){let h=e[r[D]],P=h.length,d=new Float32Array(P*3),b=new Float32Array(P*i);for(let l=0;l<P;l++)d.set(c.subarray((D*f+l)*3,(D*f+l)*3+3),l*3),b.set(C.subarray((D*f+l)*i,(D*f+l)*i+i),l*i);let I={bioLogits:d,clsLogits:b,length:P,nCls:i};s[r[D]]=this.decodeForward(h,I,0,P)}}return s}},Z=null;function EA(){return Z||(Z=new S),Z}function ve(A,e={}){return EA().parse(A,e)}function le(A,e={}){return EA().parseBatch(A,e)}function Qe(A={}){return new S(A)}export{S as Parser,Qe as createParser,V as isWebGPUAvailable,ve as parse,le as parseBatch,q as probeWebGPU};
79
+ `;function nA(){return typeof navigator<"u"&&!!navigator.gpu}var K=null;function rA(){return K||(K=(async()=>{if(!nA())return!1;try{return await navigator.gpu.requestAdapter()!==null}catch{return!1}})(),K)}var _=class{weights;state=null;constructor(B){this.weights=B}async init(){if(this.state)return this.state;if(!nA())throw new Error("WebGPU is not available in this environment");let B=await navigator.gpu.requestAdapter();if(!B)throw new Error("No WebGPU adapter available");let n=await B.requestDevice(),e=(f,w)=>{let s=n.createBuffer({size:Math.max(4,f.byteLength),usage:w,mappedAtCreation:!0});return new Float32Array(s.getMappedRange()).set(f),s.unmap(),s},t=GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,r=this.weights,g=r.conv.map(f=>({w:e(f.w.data,t),b:e(f.b,t)}));return this.state={device:n,embedModule:n.createShaderModule({code:eB}),convModule:n.createShaderModule({code:nB}),headModule:n.createShaderModule({code:rB}),embedBuf:e(r.embed.data,t),convBufs:g,bioBuf:{w:e(r.bio.w.data,t),b:e(r.bio.b,t)},clsBuf:{w:e(r.cls.w.data,t),b:e(r.cls.b,t)}},this.state}async run(B,n,e){let t=await this.init(),{device:r}=t,g=this.weights,f=g.embed.shape[1],w=GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC,s=GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,P=r.createBuffer({size:B.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST,mappedAtCreation:!0});new Int32Array(P.getMappedRange()).set(B),P.unmap();let u=E=>{let c=r.createBuffer({size:E.byteLength,usage:s,mappedAtCreation:!0});return new Uint32Array(c.getMappedRange()).set(E),c.unmap(),c},o=r.limits?.maxComputeWorkgroupsPerDimension??65535,C=E=>{let c=Math.max(1,Math.ceil(E/64)),a=Math.min(c,o),d=Math.ceil(c/a);return{x:a,y:d,stride:a*64}},D=(E,c,a)=>{let d=r.createBindGroup({layout:E.getBindGroupLayout(0),entries:c}),F=r.createCommandEncoder(),l=F.beginComputePass();l.setPipeline(E),l.setBindGroup(0,d),l.dispatchWorkgroups(a.x,a.y),l.end(),r.queue.submit([F.finish()])},Q=r.createBuffer({size:n*f*e*4,usage:w});{let E=C(n*e),c=u(new Uint32Array([n,e,f,g.embed.shape[0],E.stride])),a=r.createComputePipeline({layout:"auto",compute:{module:t.embedModule,entryPoint:"main"}});D(a,[{binding:0,resource:{buffer:c}},{binding:1,resource:{buffer:P}},{binding:2,resource:{buffer:t.embedBuf}},{binding:3,resource:{buffer:Q}}],E)}let i=f,I=g.conv,v=r.createComputePipeline({layout:"auto",compute:{module:t.convModule,entryPoint:"main"}});for(let E=0;E<I.length;E++){let c=I[E],[a,,d]=c.w.shape,F=c.dilation,l=c.padding,z=r.createBuffer({size:n*a*e*4,usage:w}),y=C(n*a*e),hA=u(new Uint32Array([n,e,i,a,d,l,F,1,c.residual?1:0,y.stride]));D(v,[{binding:0,resource:{buffer:hA}},{binding:1,resource:{buffer:Q}},{binding:2,resource:{buffer:t.convBufs[E].w}},{binding:3,resource:{buffer:t.convBufs[E].b}},{binding:4,resource:{buffer:z}}],y),Q=z,i=a}let h=r.createComputePipeline({layout:"auto",compute:{module:t.headModule,entryPoint:"main"}}),b=async(E,c)=>{let a=r.createBuffer({size:n*e*c*4,usage:w}),d=C(n*e*c),F=u(new Uint32Array([n,e,i,c,d.stride]));D(h,[{binding:0,resource:{buffer:F}},{binding:1,resource:{buffer:Q}},{binding:2,resource:{buffer:E.w}},{binding:3,resource:{buffer:E.b}},{binding:4,resource:{buffer:a}}],d);let l=r.createBuffer({size:n*e*c*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ}),z=r.createCommandEncoder();z.copyBufferToBuffer(a,0,l,0,n*e*c*4),r.queue.submit([z.finish()]),await l.mapAsync(GPUMapMode.READ);let y=new Float32Array(l.getMappedRange().slice(0));return l.unmap(),y},L=await b(t.bioBuf,g.bio.w.shape[0]),H=await b(t.clsBuf,g.cls.w.shape[0]);return{bio:L,cls:H}}};var lA={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","\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:[114,16],scale:.026793908327817917,data_b64:"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"},conv:[{k:5,dilation:1,residual:!1,w:{shape:[48,16,5],scale:.006297729909420013,data_b64:"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"},b:[-.41403,-.37083,-.17471,-.10723,-.217,-.12782,-.13307,-.17872,.14632,.22011,-.51505,-.49735,-.37585,-.09941,-.28281,-.019124,-.42833,.035917,-.10015,-.15915,-.25731,-.26232,-.0039441,-.27283,-.15598,-.25122,-.0023473,-.22346,-.29785,-.20515,-.19531,-.4258,-.18466,-.01237,.29463,-.2259,-.34927,.099886,-.44475,.075165,-.23074,-.3804,-.36044,-.20509,-.13041,-.65456,-.15375,-.27194]},{k:3,dilation:1,residual:!0,w:{shape:[48,48,3],scale:.011268280446529388,data_b64:"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"},b:[-.11524,-.18613,.1175,-.24892,.044796,.036463,.162,.1028,.29527,.66518,.22132,.018315,.021825,-.035526,-.079711,.003407,.027631,.018111,.091177,.19069,-.014315,.14228,.56057,.094511,-.2393,.14826,.15474,.080275,.10113,-.0066077,.18899,.37924,.22151,.15665,.025146,.12335,.039528,.020341,.17161,.30304,.089673,.7569,-.26167,-.43312,-.10887,-.15408,.089991,.14783]},{k:3,dilation:2,residual:!0,w:{shape:[48,48,3],scale:.01531923096626997,data_b64:"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"},b:[.32767,.15526,.082936,-.049189,-.054941,-.15,.26939,.011199,82305e-8,1.0392,.2586,-.35586,.59987,.199,.1843,.024139,-.021032,.021746,.068581,.1081,-.066881,.28893,.89474,.89374,.0083983,.010518,.63441,.033195,.63983,.12939,.35362,.14388,1.1091,.2411,-.18525,.38478,-.054586,.68936,-.039841,.35021,.042444,1.2556,-.077732,-.63378,-.12078,.63872,-.024576,.76438]},{k:3,dilation:4,residual:!0,w:{shape:[48,48,3],scale:.017100131139159203,data_b64:"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"},b:[1.3777,.085752,.28277,-.0026793,-.36331,.26844,.23482,.45244,-1.3456,.32375,.62031,-.2426,.0069488,.28055,1.2795,.49334,.092458,.021483,.35107,.12564,.094297,.33727,1.1613,.91248,.33595,-.31547,1.0323,.48746,-.51575,.62476,.13256,.57825,1.5317,.17567,.028722,.71635,-.029699,-.071299,.67362,.67226,.57821,1.9162,.22972,-.058133,-.21721,1.7296,-.063783,1.2866]},{k:3,dilation:8,residual:!0,w:{shape:[48,48,3],scale:.01713515631854534,data_b64:"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"},b:[.17334,.95171,.39722,.81052,.1426,.24649,.26206,-1.6457,.60351,.68078,.32679,-.072643,-1.4102,-.10251,-.77406,.49564,-.033894,.076563,.036676,-.66481,-.080242,.22412,.46619,1.2746,.53776,.49293,.26188,.56415,-.41336,-.037646,.33929,.76413,.56441,.18243,.5228,-95438e-10,-.11429,.43393,.4121,-.025991,.0081522,1.6035,.041022,.06896,.15759,1.8212,-.1321,.81853]}],bio:{w:{shape:[3,48],scale:.004121375735849142,data_b64:"KP707AkH9PmB9RL0dgJFDxD4ASj2ADr27AgHFQIH9PgXzeMA/QHvLQ4FAP76/wb52gD+7gwJ9/IM9xDu9wT4ERP3/FX7/yD67Q0FEwT09fYMFtL68wTsVgAB/gIGuAb62gH67AoK+vA/9hEAiwTwEBr48+X7Adbt7BEFEgL29fcLFkQIBwXuwCH//gIE9Qb7"},b:[.33826,-.72342,.082475]},cls:{w:{shape:[120,48],scale:.006543000228703022,data_b64:"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"},b:[2.1537,.47451,.029461,.89724,-.12645,-1.3064,-.42351,-.070797,.34355,.20397,-.43014,-.063977,-.11719,-.34141,-.37835,-.64427,-.53819,-.47944,-.56216,-.12763,-.48014,-.56977,.050473,-.33839,-.65921,-.31452,-.33799,.10971,.078488,-.45741,-.15056,-.018883,-.27828,-.17847,-.81039,-.28268,-.14222,-.29722,-.77616,-.47762,-.3697,-.46026,-.13087,-.49869,-.28312,-.69974,-.41188,-.92325,-.58822,-.39002,-.77904,-.36065,-.11276,-.51998,-.6679,-.38287,-.65133,-.40006,-.26539,-.30836,-.44642,-.63607,-.34191,-.47544,-.56102,-.12988,-.55126,-.47222,-.1993,-.83675,-.95856,-.1607,-.10582,-.52014,-.43954,-.43493,-.62038,-.5219,-.36894,-.45107,-.21352,-.24609,-.35412,-.22215,-.3239,.0019337,-.40894,-.61599,-.35282,-.37185,-.41393,-.5583,-.21046,-.82141,-.49686,-.81666,-.62528,-.17747,-.33321,-.42288,-.37428,-.17428,-1.1207,-.22147,-.65601,-.58428,-.5439,-.10838,-.0096173,-.40622,-.38756,-1.0267,.49986,.42088,.80243,-.025016,.4964,-.71379,.045631,-.52001]}};var V=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(B={}){this.weights=gA(B.weights??lA),this.charToId=sA(this.weights.charset),this.defaultBackend=B.backend??"cpu",this.scratch=new X(this.weights)}parse(B,n={}){let e=B;B=k(B);let t=e.length===B.length,r,g=Z(B.length);if(g.length===1&&g[0].length===B.length){let f=x(B.length),w=p(B,this.charToId,this.idsScratch,f),s=j(this.weights,w,this.scratch);r=this.decodeForward(B,s,0,B.length)}else{let f=[],w=new Set;for(let s of g){let P=B.slice(s.offset,s.offset+s.length),u=x(P.length),o=p(P,this.charToId,this.idsScratch,u),C=j(this.weights,o,this.scratch),D=this.decodeForward(P,C,s.offset,P.length);for(let Q of D){let i=`${Q.start}:${Q.end}`;w.has(i)||(w.add(i),f.push(Q))}}f.sort((s,P)=>s.start-P.start),r=f}if(t)for(let f of r)f.span=e.slice(f.start,f.end);return r}decodeForward(B,n,e,t=n.length){let r=t,g=r<=128,f=g?this.bioIdsScratch:new Int32Array(r),w=g?this.clsIdsScratch:new Int32Array(r),s=g?this.bioProbsScratch:Array.from({length:r},()=>new Float32Array(3));for(let o=0;o<r;o++)f[o]=G(n.bioLogits,o*3,3),w[o]=G(n.clsLogits,o*n.nCls,n.nCls),$(n.bioLogits,o*3,3,s[o]);let P=cA(B,f.subarray(0,r),w.subarray(0,r),s),u=[];for(let o of P){let C=o.tokens.map(([i,I])=>[M[i],I]),D=aA(C),Q=IA(B,o.start,o.end,tB);u.push({span:o.text,start:o.start+e,end:o.end+e,value:D.value,...D.range?{range:D.range}:{},unit:D.unit??null,currency:Q,confidence:o.confidence??0,classes:D.classes})}return u}inspect(B){let n=performance.now(),e=k(B),t=Z(e.length),r=new Array(e.length),g=new Array(e.length).fill(!1);for(let s of t){let P=e.slice(s.offset,s.offset+s.length),u=x(P.length),o=p(P,this.charToId,this.idsScratch,u),C=j(this.weights,o,this.scratch);for(let D=0;D<P.length;D++){let Q=s.offset+D;if(g[Q])continue;g[Q]=!0;let i=G(C.bioLogits,D*3,3),I=new Float32Array(3);$(C.bioLogits,D*3,3,I);let v=G(C.clsLogits,D*C.nCls,C.nCls);r[Q]={ch:P[D],bio:i,bioProb:[I[0],I[1],I[2]],cls:M[v],clsId:v}}}let f=this.parse(B),w=performance.now()-n;return{text:e,chars:r,spans:f,ms:w}}modelInfo(){let B=this.weights,n=B.embed.data.length;for(let t of B.conv)n+=t.w.data.length+t.b.length;n+=B.bio.w.data.length+B.bio.b.length,n+=B.cls.w.data.length+B.cls.b.length;let e=B.conv.length?Math.max(...B.conv.map(t=>t.w.shape[0])):B.embed.shape[1];return{version:B.version,params:n,channels:e,embedDim:B.embed.shape[1],vocab:B.embed.shape[0],classes:B.classes.length,layers:B.conv.map(t=>({k:t.k,dilation:t.dilation,residual:t.residual}))}}async parseBatch(B,n={}){let e=n.backend??this.defaultBackend;if(!(e==="webgpu"||e==="auto"&&B.length>=32&&await rA()))return B.map(P=>this.parse(P,{backend:"cpu"}));let r=B,g=B.map(k),f=new Array(B.length),w=[],s=[];for(let P=0;P<g.length;P++)g[P].length<=128?w.push(P):s.push(P);for(let P of s)f[P]=this.parse(r[P],{backend:"cpu"});if(w.length>0){this.gpu||(this.gpu=new _(this.weights));let P=Math.max(...w.map(v=>g[v].length),1),u=x(P),o=w.length,C=new Int32Array(o*u),D=this.charToId.get("<pad>")??0;C.fill(D);for(let v=0;v<o;v++){let h=g[w[v]],b=p(h,this.charToId);C.set(b,v*u)}let{bio:Q,cls:i}=await this.gpu.run(C,o,u),I=this.weights.cls.w.shape[0];for(let v=0;v<o;v++){let h=w[v],b=g[h],L=r[h],H=L.length===b.length,E=b.length,c=new Float32Array(E*3),a=new Float32Array(E*I);for(let l=0;l<E;l++)c.set(Q.subarray((v*u+l)*3,(v*u+l)*3+3),l*3),a.set(i.subarray((v*u+l)*I,(v*u+l)*I+I),l*I);let d={bioLogits:c,clsLogits:a,length:E,nCls:I},F=this.decodeForward(b,d,0,E);if(H)for(let l of F)l.span=L.slice(l.start,l.end);f[h]=F}}return f}},fA=null;function q(){return fA||(fA=new V),fA}function FB(A,B={}){return q().parse(A,B)}function MB(A,B={}){return q().parseBatch(A,B)}function RB(A){return q().inspect(A)}function OB(){return q().modelInfo()}function xB(A={}){return new V(A)}var tB=iA(HA,bA);export{M as CLASSES,V as Parser,xB as createParser,RB as inspect,nA as isWebGPUAvailable,OB as modelInfo,k as normalizeText,FB as parse,MB as parseBatch,rA as probeWebGPU};
@@ -0,0 +1,2 @@
1
+ import type { LangPack } from "./core.js";
2
+ export declare const HI_DEVA: LangPack;
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,8 +1,8 @@
1
1
  {
2
2
  "name": "gpu-sankhya",
3
- "version": "0.1.2",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
- "description": "Fast char-CNN extraction of Hinglish (Latin-script Hindi) numeric quantities, with CPU and WebGPU backends.",
5
+ "description": "Fast char-CNN extraction of Hinglish and Devanagari Hindi numeric quantities, with CPU and WebGPU backends.",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",