gpu-sankhya 0.1.1 → 0.2.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 +89 -44
- package/dist/charset.d.ts +16 -0
- package/dist/core.d.ts +5 -0
- package/dist/index.d.ts +9 -1
- package/dist/index.js +10 -10
- package/dist/lang-hi-deva.d.ts +2 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
# gpu-sankhya
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/gpu-sankhya)
|
|
4
|
+
[](https://www.npmjs.com/package/gpu-sankhya?activeTab=code)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
[](https://athrvk.github.io/gpu-sankhya/)
|
|
7
|
+
|
|
3
8
|
Parses Indian informal number/currency shorthand — Hinglish (romanised
|
|
4
|
-
Hindi) and Indian-English amount phrases like `sava
|
|
5
|
-
`2.5L`, `20k`, `2-3 lakh` —
|
|
6
|
-
unit, currency, and confidence
|
|
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.
|
|
7
15
|
|
|
8
16
|
A small char-level CNN tags each character of the input with a BIO span
|
|
9
17
|
label and a semantic token class (digit, prefix word like "sava"/"dedh",
|
|
@@ -60,6 +68,22 @@ parse("sawaa laakh ka budget hai");
|
|
|
60
68
|
// variance ("sawaa"/"sava", "laakh"/"lakh") is part of the training data,
|
|
61
69
|
// not special-cased.
|
|
62
70
|
|
|
71
|
+
// Devanagari input follows the same grammar/arithmetic as Hinglish (the
|
|
72
|
+
// core is language-independent -- see How it works); the expected output
|
|
73
|
+
// shape is identical, e.g.:
|
|
74
|
+
parse("डेढ़ लाख");
|
|
75
|
+
// [{ span: "डेढ़ लाख", value: 150000, unit: "lakh", ... }]
|
|
76
|
+
|
|
77
|
+
parse("सवा दो करोड़ का फ्लैट");
|
|
78
|
+
// [{ span: "सवा दो करोड़", value: 22500000, unit: "crore", ... }]
|
|
79
|
+
|
|
80
|
+
parse("बजट साढ़े तीन लाख है");
|
|
81
|
+
// [{ span: "साढ़े तीन लाख", value: 350000, unit: "lakh", ... }]
|
|
82
|
+
// NOTE: the correctness of these Devanagari examples depends on the
|
|
83
|
+
// bundled weights being trained on the hi_deva pack (see python/README.md);
|
|
84
|
+
// the runtime-side normalization/decoding/currency support is in place
|
|
85
|
+
// independent of which weights are loaded (createParser({ weights })).
|
|
86
|
+
|
|
63
87
|
// batch (uses WebGPU automatically for large batches in a browser, else CPU)
|
|
64
88
|
const results = await parseBatch(["sava lakh", "dedh crore", "..."]);
|
|
65
89
|
|
|
@@ -105,6 +129,16 @@ interface Sankhya {
|
|
|
105
129
|
actually obtained. Result is cached, so repeated calls only probe once.
|
|
106
130
|
`parseBatch`'s `"auto"` backend uses this (not `isWebGPUAvailable()`)
|
|
107
131
|
to decide whether to try the GPU path.
|
|
132
|
+
- **`normalizeText(text) => string`** — the exact normalization
|
|
133
|
+
`parse`/`parseBatch` apply before char-encoding (Unicode NFC, then
|
|
134
|
+
Devanagari digits U+0966-U+096F mapped 1:1 to ASCII `"0"`-`"9"`, then
|
|
135
|
+
lowercasing), exposed so callers can reproduce the same offsets. `parse`
|
|
136
|
+
returns `start`/`end` as indices into `normalizeText(text)`, not the raw
|
|
137
|
+
input — for the overwhelming majority of input, which already arrives in
|
|
138
|
+
NFC form, normalization never changes the string's length, so offsets
|
|
139
|
+
are unaffected; call `normalizeText` yourself first if you need to be
|
|
140
|
+
sure for non-NFC input. The `span` field is a substring of your original
|
|
141
|
+
input when lengths match, and of the normalized string otherwise.
|
|
108
142
|
|
|
109
143
|
## Backends
|
|
110
144
|
|
|
@@ -131,50 +165,56 @@ batch — hundreds of strings at once — which is exactly what `parseBatch`
|
|
|
131
165
|
does with `backend: "auto"`/`"webgpu"`; `parse()` stays CPU-only and
|
|
132
166
|
synchronous on purpose.
|
|
133
167
|
|
|
134
|
-
The WebGPU path
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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.
|
|
138
173
|
|
|
139
174
|
## Accuracy
|
|
140
175
|
|
|
141
|
-
The bundled default model:
|
|
176
|
+
The bundled default model: 18,811 parameters, 4 conv layers (kernel sizes
|
|
142
177
|
3/5/3/3, dilations 1/1/2/4, 32 channels), 16-dim char embeddings over a
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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`).
|
|
146
182
|
|
|
147
183
|
On synthetic validation data (drawn from the same generator/templates as
|
|
148
|
-
training): 0.
|
|
184
|
+
training): 0.92 value accuracy. This number is optimistic — it's testing
|
|
149
185
|
the model on its own distribution.
|
|
150
186
|
|
|
151
|
-
On
|
|
152
|
-
|
|
187
|
+
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
|
|
190
|
+
spans) — evaluated against the shipped int8-quantized weights:
|
|
153
191
|
|
|
154
|
-
|
|
|
155
|
-
| --- |
|
|
156
|
-
|
|
|
157
|
-
|
|
|
158
|
-
|
|
|
159
|
-
| span F1 | 0.93 |
|
|
192
|
+
| gold set | examples | spans | value accuracy | span precision | span recall | span F1 |
|
|
193
|
+
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
|
|
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 |
|
|
160
197
|
|
|
161
|
-
**The gold
|
|
198
|
+
**The gold numbers are the ones to trust.** Known miss categories, in rough
|
|
162
199
|
order of frequency:
|
|
163
200
|
|
|
164
201
|
- unusual typos the noise model doesn't cover (e.g. "croer" for "crore")
|
|
165
202
|
- possessive apostrophes ("do lakh's")
|
|
166
|
-
- long multi-term
|
|
203
|
+
- long multi-term/mixed-numeral constructs ("three n half lakh", "50M")
|
|
204
|
+
- multi-number range phrases ("तीस पैंतीस हज़ार", "paanch se sadhe saat lakh")
|
|
167
205
|
- occasional spurious spans triggered by unfamiliar words near number-ish
|
|
168
206
|
context
|
|
169
207
|
|
|
170
208
|
Reproduce these numbers yourself with
|
|
171
|
-
`python -m sankhya.eval_gold --gold tests/gold.jsonl --weights-json src/data/default-weights.json --int8`
|
|
209
|
+
`python -m sankhya.eval_gold --gold tests/gold.jsonl tests/gold_deva.jsonl --weights-json src/data/default-weights.json --int8`
|
|
172
210
|
from `python/` (see `python/README.md`).
|
|
173
211
|
|
|
174
212
|
## How it works
|
|
175
213
|
|
|
176
|
-
1. The input string is
|
|
177
|
-
|
|
214
|
+
1. The input string is normalized (`normalizeText`: Unicode NFC, then
|
|
215
|
+
Devanagari digits U+0966-U+096F mapped to ASCII `"0"`-`"9"`, then
|
|
216
|
+
lowercased — byte-identical to the Python reference) and char-encoded
|
|
217
|
+
against the model's vocab (unknown chars map to `<unk>`).
|
|
178
218
|
2. A 4-layer dilated conv1d stack (see Accuracy above) produces, per
|
|
179
219
|
character, a 3-way BIO logit (O/B/I) and a class logit over the
|
|
180
220
|
semantic token vocabulary (prefix words, cardinals, units, digits,
|
|
@@ -221,11 +261,20 @@ outputs are discarded; only the real characters' predictions are used.
|
|
|
221
261
|
|
|
222
262
|
## Limitations
|
|
223
263
|
|
|
224
|
-
- **
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
264
|
+
- **Hinglish and Devanagari Hindi.** Romanised Hindi / Indian-English
|
|
265
|
+
amount phrases and Devanagari-script Hindi (`डेढ़ लाख`, `सवा करोड़`) are
|
|
266
|
+
both supported, including mixed-script input in the same string.
|
|
267
|
+
Currency and unit detection scan the Latin (`hi_latn`) and Devanagari
|
|
268
|
+
(`hi_deva`) marker lists together. Other Indian languages (Marathi,
|
|
269
|
+
Gujarati, Bengali, Tamil/Telugu/Kannada) are planned via additional
|
|
270
|
+
language packs (the arithmetic core is already language-independent;
|
|
271
|
+
only the class vocabulary and currency-marker lists are per-language) —
|
|
272
|
+
see Roadmap. Devanagari accuracy depends on the bundled weights being
|
|
273
|
+
trained on the `hi_deva` pack; see Devanagari gold-set numbers above.
|
|
274
|
+
- **Offsets are into the normalized string.** `parse()`'s `start`/`end`
|
|
275
|
+
index `normalizeText(text)`, not the raw input, in the rare case NFC
|
|
276
|
+
normalization changes the string's length (see `normalizeText` in the
|
|
277
|
+
API section above).
|
|
229
278
|
- Text longer than 128 characters is processed with a sliding window
|
|
230
279
|
(128-char windows, 16-char overlap) and results are merged/deduplicated
|
|
231
280
|
by span; extremely long inputs may still miss a span that straddles a
|
|
@@ -265,20 +314,17 @@ outputs are discarded; only the real characters' predictions are used.
|
|
|
265
314
|
Everything here is scoped to Indian languages — there's no plan to
|
|
266
315
|
support non-Indian numbering/currency shorthand.
|
|
267
316
|
|
|
268
|
-
1.
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
317
|
+
1. ~~**Devanagari Hindi pack** (डेढ़ लाख).~~ **Done.** The `hi_deva`
|
|
318
|
+
language pack, Devanagari currency markers, Unicode-aware (`\p{L}`/
|
|
319
|
+
`\p{M}`) letters-run repair for matras/nukta/virama, and input
|
|
320
|
+
normalization (NFC + Devanagari-digit mapping) are all in place, and
|
|
321
|
+
mixed Latin/Devanagari input is supported. See `python/README.md` for
|
|
322
|
+
the training-side status and gold-set numbers.
|
|
273
323
|
2. **Other Indian languages as packs**: Marathi (साडे, सव्वा), Gujarati
|
|
274
324
|
(સવા, દોઢ), Bengali (দেড়, আড়াই), and Tamil/Telugu/Kannada number
|
|
275
325
|
words. Same shape as (1) — a new pack, a new noise function, a charset
|
|
276
326
|
rebuild.
|
|
277
|
-
3. **
|
|
278
|
-
been exercised in Node (falling back to CPU there), but has not yet
|
|
279
|
-
been run against a real GPU in a browser — needs that verification
|
|
280
|
-
pass before it should be relied on.
|
|
281
|
-
4. **A WASM SIMD kernel**, if sub-millisecond latency is ever needed
|
|
327
|
+
3. **A WASM SIMD kernel**, if sub-millisecond latency is ever needed
|
|
282
328
|
beyond what the plain-JS CPU path already gives.
|
|
283
329
|
|
|
284
330
|
## Development
|
|
@@ -308,10 +354,9 @@ You can also just edit the `version` field in `package.json` in a PR — no
|
|
|
308
354
|
need to run `npm version` or create a tag yourself. Either way, once the
|
|
309
355
|
new version lands on master, the `publish` workflow detects that
|
|
310
356
|
`package.json`'s version isn't on npm yet, builds, tests, publishes (with
|
|
311
|
-
provenance), and creates the matching git tag
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
`workflow_dispatch`, also triggers a publish.
|
|
357
|
+
provenance), and creates the matching `vX.Y.Z` git tag if it does not
|
|
358
|
+
exist yet. Running the workflow manually via `workflow_dispatch` does the
|
|
359
|
+
same check and publishes only if the version is not on npm.
|
|
315
360
|
|
|
316
361
|
Trusted publishing (OIDC, no `NPM_TOKEN`) must be configured once on
|
|
317
362
|
npmjs.com for this to work: package page -> Settings -> Trusted publisher,
|
package/dist/charset.d.ts
CHANGED
|
@@ -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,7 @@
|
|
|
1
1
|
import type { Sankhya, ParseOptions, WeightsJson } from "./types.js";
|
|
2
2
|
export type { Sankhya, ParseOptions } from "./types.js";
|
|
3
3
|
export { isWebGPUAvailable, probeWebGPU } from "./infer-webgpu.js";
|
|
4
|
+
export { normalizeText } from "./charset.js";
|
|
4
5
|
export interface CreateParserOptions {
|
|
5
6
|
weights?: WeightsJson;
|
|
6
7
|
backend?: "cpu" | "webgpu" | "auto";
|
|
@@ -16,7 +17,14 @@ export declare class Parser {
|
|
|
16
17
|
private clsIdsScratch;
|
|
17
18
|
private bioProbsScratch;
|
|
18
19
|
constructor(opts?: CreateParserOptions);
|
|
19
|
-
/** Synchronous CPU parse of a single string.
|
|
20
|
+
/** Synchronous CPU parse of a single string.
|
|
21
|
+
*
|
|
22
|
+
* The returned spans/offsets (`start`, `end`, and `span` when the
|
|
23
|
+
* normalized string's length differs from the input's) are indices into
|
|
24
|
+
* `normalizeText(text)`, not the raw `text` argument -- see
|
|
25
|
+
* normalizeText() in charset.ts. For the overwhelming majority of real
|
|
26
|
+
* input, which already arrives in NFC form, normalization never changes
|
|
27
|
+
* string length, so offsets and `span` are identical either way. */
|
|
20
28
|
parse(text: string, opts?: ParseOptions): Sankhya[];
|
|
21
29
|
/** `fw` may cover a padded length (PAD_TAIL right-padding, see charset.ts);
|
|
22
30
|
* `realLen` (defaults to fw.length, i.e. no padding) bounds decoding to the
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
function QA(A){return A.quantized!==void 0}function EA(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 q(A){let e=EA(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 Z(A){return{shape:A.shape,data:Float32Array.from(A.data)}}function $(A){let e=A.layers??3,n=A.dilation??2,t=["conv1","conv2","conv3",...e===4?["conv4"]:[]];if(QA(A)){let r={layers:e,dilation:n,charset:A.charset,classes:A.classes,embed:q(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:q(u.w),b:Float32Array.from(u.b)}}return r}let a=A,s={layers:e,dilation:n,charset:a.charset,classes:a.classes,embed:Z(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:Z(o.w),b:Float32Array.from(o.b.data)}}return s}function bA(A){return Math.ceil(A/8)*8}function M(A){return bA(A+16)}var H=M(128);function AA(A){let e=new Map;for(let n=0;n<A.length;n++)e.set(A[n],n);return e}function F(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 eA(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 U=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 x(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 P=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,v=g[C],h=C*e*B;if(B===3){for(let w=0;w<n;w++)r[i+w]=v;for(let w=0;w<e;w++){let I=w*c,b=h+w*3,l=P[b],D=P[b+1],Q=P[b+2];for(let d=0;d<n;d++){let E=I+d;r[i+d]+=l*o[E]+D*o[E+s]+Q*o[E+2*s]}}}else if(B===5){for(let w=0;w<n;w++)r[i+w]=v;for(let w=0;w<e;w++){let I=w*c,b=h+w*5,l=P[b],D=P[b+1],Q=P[b+2],d=P[b+3],E=P[b+4];for(let p=0;p<n;p++){let R=I+p;r[i+p]+=l*o[R]+D*o[R+1]+Q*o[R+2]+d*o[R+3]+E*o[R+4]}}}else{for(let w=0;w<n;w++)r[i+w]=v;for(let w=0;w<e;w++){let I=w*c,b=h+w*B;for(let l=0;l<B;l++){let D=P[b+l],Q=l*s,d=I+Q;for(let E=0;E<n;E++)r[i+E]+=D*o[d+E]}}}for(let w=0;w<n;w++){let I=r[i+w];r[i+w]=I>0?I:0}}return u}function nA(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 P=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[P+g]=c}}return s}function X(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 v=0;v<s;v++)r[v*t+c]=a.data[i+v]}let o=s,u=n.paddedBuf(),f=n.buf(1);o=x(r,o,t,A.conv1,1,1,f,u),r=f,f=n.buf(2),o=x(r,o,t,A.conv2,2,1,f,u),r=f;let B=A.dilation,P=Math.floor(B*2/2);if(f=n.buf(3),o=x(r,o,t,A.conv3,P,B,f,u),r=f,A.layers===4&&A.conv4){let C=Math.floor(4);f=n.buf(4),o=x(r,o,t,A.conv4,C,4,f,u),r=f}nA(r,o,t,A.bio,n.bioBuf);let g=nA(r,o,t,A.cls,n.clsBuf);return{bioLogits:n.bioBuf,clsLogits:n.clsBuf,length:t,nCls:g}}function tA(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 S(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 hA=["PFX_PAAV","PFX_AADHA","PFX_PAUNE","PFX_SAVA","PFX_DEDH","PFX_DHAI","PFX_SAADHE"],dA=Array.from({length:99},(A,e)=>`CARD_${e+1}`),IA=["UNIT_SAU","UNIT_HAZAAR","UNIT_LAKH","UNIT_MILLION","UNIT_CRORE","UNIT_BILLION","UNIT_ARAB","UNIT_KHARAB"],pA=["O","SEP","RANGE","DIGITS","DOT","COMMA"],L=["O",...pA.filter(A=>A!=="O"),...hA,...dA,...IA],y=Object.fromEntries(L.map((A,e)=>[A,e])),rA={UNIT_SAU:100,UNIT_HAZAAR:1e3,UNIT_LAKH:1e5,UNIT_MILLION:1e6,UNIT_CRORE:1e7,UNIT_BILLION:1e9,UNIT_ARAB:1e9,UNIT_KHARAB:1e11},_={UNIT_SAU:"sau",UNIT_HAZAAR:"hazaar",UNIT_LAKH:"lakh",UNIT_MILLION:"million",UNIT_CRORE:"crore",UNIT_BILLION:"billion",UNIT_ARAB:"arab",UNIT_KHARAB:"kharab"},j={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 sA(A){return A in j}function oA(A){return A.startsWith("CARD_")}function fA(A){return A in rA}function aA(A){return parseInt(A.split("_",2)[1],10)}function O(A){return rA[A]}var uA=new Set(["SEP","RANGE","DOT","COMMA"]),HA=["PFX_","CARD_","UNIT_"],LA=["PFX_","CARD_","UNIT_"];function yA(A){return HA.some(e=>A.startsWith(e))||A==="DIGITS"}function MA(A){return LA.some(e=>A.startsWith(e))}var FA=y.O,m=y.SEP,Y=y.RANGE,xA=y.DIGITS,UA=y.DOT,OA=y.COMMA;function BA(A){return/[a-z]/i.test(A)?"letter":/[0-9]/.test(A)?"digit":/\s/.test(A)?"space":"punct"}function mA(A){let e=[],n=0,t=A.length;for(;n<t;){let a=BA(A[n]),s=n+1;for(;s<t&&BA(A[s])===a;)s++;e.push({type:a,start:n,end:s}),n=s}return e}function TA(A,e,n){let t=new Map;for(let f=e;f<n;f++){let B=A[f];MA(L[B])&&t.set(B,(t.get(B)??0)+1)}if(t.size===0)return FA;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,P=0,g=1/0;for(let c=e;c<n;c++)A[c]===f?(g===1/0&&(g=c),B++,B>P&&(P=B)):B=0;(P>r||P===r&&g<o)&&(r=P,o=g,u=f)}return u}function GA(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=TA(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,P=o<t.length-1?t[o+1]:null,g=B!==null&&B.end-B.start>=3,c=P!==null&&P.end-P.start>=3,C;if(g&&c){let i=B.end-B.start;C=P.end-P.start>i?P.cls:B.cls}else g?C=B.cls:c?C=P.cls:C=s;r.push([u.start,u.end,C])}return r}function zA(A,e){let n=A.length,t=new Array(n),a=mA(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]=xA;continue}if(o==="space"){let c=!1;for(let i=u;i<f;i++)if(e[i]===Y){c=!0;break}let C=c?Y:m;for(let i=u;i<f;i++)t[i]=C;continue}if(o==="letter"){for(let[c,C,i]of GA(e,u,f))for(let v=c;v<C;v++)t[v]=i;continue}let B=s>0?a[s-1].type:null,P=s<a.length-1?a[s+1].type:null,g=m;if(f-u===1){let c=A[u];(c==="."||c===",")&&B==="digit"&&P==="digit"?g=c==="."?UA:OA:(c==="-"||c==="\u2013"||c==="/")&&B==="digit"&&P==="digit"?g=Y:g=m}for(let c=u;c<f;c++)t[c]=g}return t}function kA(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 cA(A){return A!==void 0&&A>="0"&&A<="9"}function NA(A,e,n){if(n<=e||!cA(A[n-1]))return n;let t=n;for(;t<A.length&&cA(A[t]);)t++;return t}function gA(A,e,n,t){let a=A.length,s=kA(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],NA(A,r[f][0],r[f][1])];let u=[];for(let[f,B]of r){let P=A.slice(f,B),g=Array.from({length:B-f},(D,Q)=>n[f+Q]),c=zA(P,g),C=f,i=[];for(let D=f+1;D<=B;D++)(D===B||c[D-f]!==c[C-f])&&(i.push([c[C-f],C,D]),C=D);let v=0,h=i.length;for(;v<h&&uA.has(L[i[v][0]]);)v++;for(;h>v&&uA.has(L[i[h-1][0]]);)h--;let w=i.slice(v,h);if(w.length===0)continue;let I=w[0][1],b=w[w.length-1][2];if(!w.some(([D])=>yA(L[D])))continue;let l=null;if(t){let D=[];for(let Q=I;Q<b;Q++)D.push(Math.max(...t[Q]));if(l=D.length?D.reduce((Q,d)=>Q+d,0)/D.length:0,l<.5)continue}u.push({start:I,end:b,text:A.slice(I,b),tokens:w.map(([D,Q,d])=>[D,A.slice(Q,d)]),confidence:l})}return u}function XA(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 SA(A,e){if(e!==null){let n=j[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 _A(A){let e=XA(A),n=0,t=null,a=null,s=null,r=null;function o(u){let f=SA(s,r);if(u===null)n+=f*1;else{let B=O(u);t!==null&&B>t?n=n*B:n=n+f*B,t=B,(a===null||B>O(a))&&(a=u)}s=null,r=null}for(let[u,f]of e)if(u==="NUM")s!==null&&o(null),s=f;else if(oA(u)){s!==null&&o(null);try{s=aA(u)}catch{}}else if(sA(u))r!==null&&o(null),r=u;else if(fA(u))o(u);else continue;return(s!==null||r!==null)&&o(null),[n,a]}function T(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 jA(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 iA(A){try{let e=A.map(g=>g[0]),n=jA(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=>_A(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:T(g),range:null,unit:c?_[c]??null:null,classes:e,currency:null}}let[s,r]=a[0],[o,u]=a[1],f;r===null&&u!==null?(s=s*O(u),f=u):f=r!==null?r:u;let[B,P]=s<=o?[s,o]:[o,s];return{value:T(B),range:[T(B),T(P)],unit:f?_[f]??null:null,classes:e,currency:null}}catch{return{value:0,range:null,unit:null,classes:A.map(e=>e[0]),currency:null}}}function CA(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 wA={currency_markers_before:["\u20B9","Rs","Rs.","rs","INR","Re"],currency_words_after:["rupaye","rupay","rupees","rupiya","rupya","/-"]};var YA=`
|
|
2
|
-
struct Params { batch: u32, length: u32, embedDim: u32, vocab: u32 };
|
|
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=`
|
|
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>;
|
|
5
5
|
@group(0) @binding(2) var<storage, read> embed: array<f32>;
|
|
@@ -7,7 +7,7 @@ struct Params { batch: u32, length: u32, embedDim: u32, vocab: u32 };
|
|
|
7
7
|
|
|
8
8
|
@compute @workgroup_size(64)
|
|
9
9
|
fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
10
|
-
let idx = gid.x;
|
|
10
|
+
let idx = gid.y * p.stride + gid.x;
|
|
11
11
|
let total = p.batch * p.length;
|
|
12
12
|
if (idx >= total) { return; }
|
|
13
13
|
let b = idx / p.length;
|
|
@@ -17,8 +17,8 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
17
17
|
xOut[(b * p.embedDim + c) * p.length + t] = embed[cid * p.embedDim + c];
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
`,
|
|
21
|
-
struct Params { batch: u32, length: u32, cIn: u32, cOut: u32, k: u32, padding: u32, dilation: u32, relu: u32 };
|
|
20
|
+
`,ee=`
|
|
21
|
+
struct Params { batch: u32, length: u32, cIn: u32, cOut: u32, k: u32, padding: u32, dilation: u32, relu: 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)
|
|
@@ -27,7 +27,7 @@ struct Params { batch: u32, length: u32, cIn: u32, cOut: u32, k: u32, padding: u
|
|
|
27
27
|
|
|
28
28
|
@compute @workgroup_size(64)
|
|
29
29
|
fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
30
|
-
let idx = gid.x;
|
|
30
|
+
let idx = gid.y * p.stride + gid.x;
|
|
31
31
|
let total = p.batch * p.cOut * p.length;
|
|
32
32
|
if (idx >= total) { return; }
|
|
33
33
|
let t = idx % p.length;
|
|
@@ -49,8 +49,8 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
49
49
|
if (p.relu != 0u && acc < 0.0) { acc = 0.0; }
|
|
50
50
|
out[(b * p.cOut + oc) * p.length + t] = acc;
|
|
51
51
|
}
|
|
52
|
-
`,
|
|
53
|
-
struct Params { batch: u32, length: u32, cIn: u32, nOut: u32 };
|
|
52
|
+
`,ne=`
|
|
53
|
+
struct Params { batch: u32, length: u32, cIn: u32, nOut: u32, stride: u32 };
|
|
54
54
|
@group(0) @binding(0) var<uniform> p: Params;
|
|
55
55
|
@group(0) @binding(1) var<storage, read> x: array<f32>; // (batch, cIn, L)
|
|
56
56
|
@group(0) @binding(2) var<storage, read> w: array<f32>; // (nOut, cIn)
|
|
@@ -59,7 +59,7 @@ struct Params { batch: u32, length: u32, cIn: u32, nOut: u32 };
|
|
|
59
59
|
|
|
60
60
|
@compute @workgroup_size(64)
|
|
61
61
|
fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
62
|
-
let idx = gid.x;
|
|
62
|
+
let idx = gid.y * p.stride + gid.x;
|
|
63
63
|
let total = p.batch * p.length * p.nOut;
|
|
64
64
|
if (idx >= total) { return; }
|
|
65
65
|
let o = idx % p.nOut;
|
|
@@ -73,4 +73,4 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
|
|
|
73
73
|
}
|
|
74
74
|
out[(b * p.length + t) * p.nOut + o] = acc;
|
|
75
75
|
}
|
|
76
|
-
`;function J(){return typeof navigator<"u"&&!!navigator.gpu}var G=null;function K(){return G||(G=(async()=>{if(!J())return!1;try{return await navigator.gpu.requestAdapter()!==null}catch{return!1}})(),G)}var z=class{weights;state=null;constructor(e){this.weights=e}async init(){if(this.state)return this.state;if(!J())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:YA}),convModule:n.createShaderModule({code:JA}),headModule:n.createShaderModule({code:KA}),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 P=l=>{let D=s.createBuffer({size:l.byteLength,usage:f,mappedAtCreation:!0});return new Uint32Array(D.getMappedRange()).set(l),D.unmap(),D},g=(l,D,Q)=>{let d=s.createBindGroup({layout:l.getBindGroupLayout(0),entries:D}),E=s.createCommandEncoder(),p=E.beginComputePass();p.setPipeline(l),p.setBindGroup(0,d),p.dispatchWorkgroups(Math.ceil(Q/64)),p.end(),s.queue.submit([E.finish()])},c=s.createBuffer({size:n*o*t*4,usage:u});{let l=P(new Uint32Array([n,t,o,r.embed.shape[0]])),D=s.createComputePipeline({layout:"auto",compute:{module:a.embedModule,entryPoint:"main"}});g(D,[{binding:0,resource:{buffer:l}},{binding:1,resource:{buffer:B}},{binding:2,resource:{buffer:a.embedBuf}},{binding:3,resource:{buffer:c}}],n*t)}let C=o,i=[r.conv1,r.conv2,r.conv3,...r.layers===4&&r.conv4?[r.conv4]:[]],v=s.createComputePipeline({layout:"auto",compute:{module:a.convModule,entryPoint:"main"}});for(let l=0;l<i.length;l++){let D=i[l],[Q,,d]=D.w.shape,E=l===2,p=l===3,R=p?4:E?r.dilation:1,vA=p?Math.floor(8/2):E?Math.floor(r.dilation*2/2):l===0?1:2,V=s.createBuffer({size:n*Q*t*4,usage:u}),lA=P(new Uint32Array([n,t,C,Q,d,vA,R,1]));g(v,[{binding:0,resource:{buffer:lA}},{binding:1,resource:{buffer:c}},{binding:2,resource:{buffer:a.convBufs[l].w}},{binding:3,resource:{buffer:a.convBufs[l].b}},{binding:4,resource:{buffer:V}}],n*Q*t),c=V,C=Q}let h=s.createComputePipeline({layout:"auto",compute:{module:a.headModule,entryPoint:"main"}}),w=async(l,D)=>{let Q=s.createBuffer({size:n*t*D*4,usage:u}),d=P(new Uint32Array([n,t,C,D]));g(h,[{binding:0,resource:{buffer:d}},{binding:1,resource:{buffer:c}},{binding:2,resource:{buffer:l.w}},{binding:3,resource:{buffer:l.b}},{binding:4,resource:{buffer:Q}}],n*t*D);let E=s.createBuffer({size:n*t*D*4,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ}),p=s.createCommandEncoder();p.copyBufferToBuffer(Q,0,E,0,n*t*D*4),s.queue.submit([p.finish()]),await E.mapAsync(GPUMapMode.READ);let R=new Float32Array(E.getMappedRange().slice(0));return E.unmap(),R},I=await w(a.bioBuf,r.bio.w.shape[0]),b=await w(a.clsBuf,r.cls.w.shape[0]);return{bio:I,cls:b}}};var PA={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:"AggnIFq+ICQlE+rU+eXvthS1MTvezwP/L+P/DyDdHszqJkMVs9TPHAniFuz+AsDw7QgC6yrq5cPm8SkeGdstAvwNHunB+AvgEUYANfoz78nq/uUO+/QE+wj/AtTPJPQ5Ft4UCPLx8Pwr8yi++Antrfra/fjr4AgaFuzs6AMvvRETvSYK+UENBevqDtD3APoX6ir4F+NOAEn1K6q1EwzoAjjZGuUPGQMn6BXn/tIY6M8h80PFyNvp7xTl9+79HNzwHPUD9gwBAsgH6AL9CSL/SeT73irlC+nu5QT/5wXhtqAV4f/uCOLjEP/s5egsOP7Oz+sqEbge0eUV1yrwAPwM9AL6HxPtOQQiyMvs6QjU1hf/9Qf6uBfjHRIM/NMawyvW7r7cAB7r7gv+JQr+BgQNHjgPE+7/AugZAxDz+zbG0Rn0R/r1MP7kB7sSr1D9xzs+HA4W0ttGKOjWCS0l8dAo7OhfVCo1BS/3X/XCwJLhEDDPAPJFAwulGjPrugz4738l+Bs1UA+/FiwU1xkk6OYQFh8aWCEVCA8Z8UXz68zyC8733Rb4Bs0SOfsgAtD7WvHnCeXf4CwvzPoGxxsC5SH6LQgtMfgSJ+YAGA78Dioo9PYmNsv/GkU//Asjxxv/A7/vJewfxg3N3i4MJPPvm/b+NwwZIgIO+wMhE+TcJTQZ7/8b2/bTBj3zBx376PEXxaXw9uYFxr756OrvvCvLu+gNYNy6FQLHDPnssebjBuvEA8jhG8/7760Is8L6xjteKGExJyQJCrnRSNgPZyTqIRX67RsI6ikI0uH+FdkbMjSWDwjO11Eq9Sf3BvnsL+HXHOUePO4D6AQiB+gm7EYALuAEtentBOI85v4m9EMFCtP1DksJLuoFz9ID2v/yJeDttSj0+S3N6xcTAswSBQ4CEcPHRCbz2RE4IOLixg8rARm8BP3/7+8bF+INB+ML+9r8+ccrDN8N6vC/8T0u/d4JEPT8Ai/60N0GPCoAGevK9woOEcjkt/wM8wT7I/sTHM7f+i4iABkMOd6/Ix7a3+AcJyQbuRUFH8MH1/H9xhQA69rbHy/+RsTzEtMn9tjbCR4CLiYP//Qr6hksD7IA0eAs9gsQC/WpBQYnU0QI/A9c+QXw9Q8XACHn7ygS+SzeE7m3Htzo/Sz++2bj9hsFysAD0xbtM97tMCVGHsoeHfvi9Q7i6i71RjcNLzAX4C4kvtbGLrYD5z3v410Y/BovQBT59yYG1wL9BPvY6NHeDgcPAXVO0A0W6Q3nwNwkECvqA+Tw/+MBGSPbGZfhCjoL7Prf/+470d7d7hkj7PgI+OvYzgcJN7PZFwwQ+OH4BNLR8j4qOd4R+uzSACo9EU8C1OAKAr//4Pnt2ki/7w7WJxjQ4sjL9pIb77PyLkPvGrdaLSQAM0gkZPMRuRQY6RP+Ctcn/xXS9fJH9Dku7vvwLxvnBNvlJtwZ7SLLChgI5hr0/MMH/tUTBQMCHhVBHRXwQv0dxxEF/LcS9rTz3CT6AB8H+b7w4ybU+t8q4Q3YNMwQaEDZA0gM9f/p/TLy/LYeQq7bEyb8Ghox9PnsAxMZ8wkMFBu9GxrY2BMjJSnSHgUL3t5K2NMw+Bv/MRwcFdIJEe76KQgRxNMEE/rJ1gv73NToBgUzAvUm3NkR+/vUIEb3JuTsQsL+6SAFyI4yNDcePu/o5b0ExAUv5euQAuv9E8vzzNn/++XT/gMt5if24gTsxjCr70JK9SQc16zr8u751isTA//YMdz//gD78iIUTuH98zHy4icOBRruFuHxH/z25UI26CbT+uTf8wkF5CDR+kdIAB/o/AOpHPb56jDwHr4KFLv2FQDvD/wL9L/FDxUDEfcO2L795C8M9iLP+ioI9DzqD/LzJb3IGvEKEVMbAAIi4tHL4SQOXDUFDA0RJP8MHP4GxhQQBD4A1voS9g0IUjYB6ej2BhUlS7AdLAoAFuUgDhDt/NUc8BPTJiTxDAPzOQMx9O/8If4AC8jJDOjaIKnML8rcwA5O6yIQ79X6yA7FIgngEQDY5dgCE+frDRMA+c/RCgUk"},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 N=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=$(e.weights??PA),this.charToId=AA(this.weights.charset),this.defaultBackend=e.backend??"cpu",this.scratch=new U(this.weights)}parse(e,n={}){let t=eA(e.length);if(t.length===1&&t[0].length===e.length){let r=M(e.length),o=F(e,this.charToId,this.idsScratch,r),u=X(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=M(o.length),f=F(o,this.charToId,this.idsScratch,u),B=X(this.weights,f,this.scratch),P=this.decodeForward(o,B,r.offset,o.length);for(let g of P){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]=S(n.bioLogits,g*3,3),u[g]=S(n.clsLogits,g*n.nCls,n.nCls),tA(n.bioLogits,g*3,3,f[g]);let B=gA(e,o.subarray(0,s),u.subarray(0,s),f),P=[];for(let g of B){let c=g.tokens.map(([v,h])=>[L[v],h]),C=iA(c),i=CA(e,g.start,g.end,wA);P.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 P}async parseBatch(e,n={}){let t=n.backend??this.defaultBackend;if(!(t==="webgpu"||t==="auto"&&e.length>=32&&await K()))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 z(this.weights));let u=Math.max(...r.map(v=>e[v].length),1),f=M(u),B=r.length,P=new Int32Array(B*f),g=this.charToId.get("<pad>")??0;P.fill(g);for(let v=0;v<B;v++){let h=e[r[v]],w=F(h,this.charToId);P.set(w,v*f)}let{bio:c,cls:C}=await this.gpu.run(P,B,f),i=this.weights.cls.w.shape[0];for(let v=0;v<B;v++){let h=e[r[v]],w=h.length,I=new Float32Array(w*3),b=new Float32Array(w*i);for(let D=0;D<w;D++)I.set(c.subarray((v*f+D)*3,(v*f+D)*3+3),D*3),b.set(C.subarray((v*f+D)*i,(v*f+D)*i+i),D*i);let l={bioLogits:I,clsLogits:b,length:w,nCls:i};s[r[v]]=this.decodeForward(h,l,0,w)}}return s}},W=null;function DA(){return W||(W=new N),W}function we(A,e={}){return DA().parse(A,e)}function Pe(A,e={}){return DA().parseBatch(A,e)}function De(A={}){return new N(A)}export{N as Parser,De as createParser,J as isWebGPUAvailable,we as parse,Pe as parseBatch,K as probeWebGPU};
|
|
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:"+vTr7fYB/gUG7gEK+e4GEQsgKR3039DmCwQIBAb49PL5GBX+9+Tl+RoiDA0gAA8ABRz/BOrxDfjm4u4A9ujn+QUPGBIYGSAfAgMm+eHc5AEkHgkOHxQVAA4G/usIEQTv8Qf+6QcB/RoV7+3a2efy9QH7DQ4A/P0KDvrvDxsPGxQdHP4aFPz3/O/l0+MTAP8E/PkC3ugCCw7/DyLy9A0ZIAYUGxD5B/0UGBAKBw4QEv384wkM8AobBwUCDhQYGQf/FwEK9/kOAPfv9f/t6P8D8uHs9uj58vT36fb26QQBABgEEiMPDRTo/er+7/fn6dTcAgX49+H158787BcMDBwWCxEkCRH5CQcABQUB+Qr8+g0N/fD4CRr++PcC8OjpAgcECgMMAxgPEf789QH2DwMUCw8PAvMOCPgA5u7s+/4QDgoCBPoDBxEcDPj+EyEJ+vIBDAb37e7I9fb7DhAA+AjKydzv/QgBCgb3DQsD9v/7+OHq8g0M/PUS7dXf/PoLEQ8FCg4aIgbw0cfR8v4JAAMO/AcDAQn+CQcAFAUODP8JDO/jxwcB19Hr/AQEFSEeB+O1rPP/++cDFgvd2uTk6/z53dbqEDg1LAH45er1+iIrDAAMBhz8Bgn+FRskJunu9d30GRgcFwfjzcjo7vrqzeT2ID4xCQEFCgUF/+rP2/byDRsG9vL59wUVCvsLHw/tCCEQAwH5EhsUBwQhIRYI+c7I8fLn7uTtA/8sQCgPDRoXEwz8E/jY5/H4BA359OTb7/IL28bw9xEpHxYECBYgEv0DIBwbB/79EP3/DyIfEAHy/e/x8evp4PvyGSEMCB7s3+v8/AD+19UEAg4ICQICDBf38iYoDhEWDf/wBfjr3d7+Cg8D/xYLCunl5PMUBv8CCfDr5OYNFAPz9f8QAfkMGPgABRYYByQtG/f49gssKgPe4QII8eD0AhH73drpDQsMFAIT4t/3EgwhDOf6FO/x4dXu8P7fyPELA/YEEQICBwAF9OHgEAALFP3e3+b/9f0aHAvp6BMUGPz59u7p+O72Fx8H/AIKCfjMwvsYHhIRECorEvgFCvMIBvwKFAL7CA4NBv3q8Pv/9ejyDAgFAhAH/vri9vT6BPf87wAAAh8GDwr57vsBCPkUDgEKEA4H/gsBCwcG9ezoAP7u+f4DCAjzDPsCAuXJyNv5ByME+Ab+DAP5+AT78/b//wP7CAbwEvT2/gD09AAF+/7yCv72+ubnBPUOAfkKCBUW/QLy8Or7BAcYBgD5+iEVHQ39ExEZChcbGQwKDiQg+PH4GTAk/QkVJx0L8NL6BgHw8M4CDAICEyAG9ubaFAcA6v7uBwnzAPYCBv/b7v/6CvvqBPzM0+QA9wIM/fz+/97t7/f0yM3wAOryAPsLFBwKB/3v9dT+BgQNDAQLEx4LCfvYwOgI9wcR9Qn/5rLZBQMF/wkOA/fe5Pj+9/jxBAAYEBIAAAL8/QUFCSIm/wUJDPsUBPrp6fbfwNj/DeTl+/wLAAcPDwMPDRgDBerc4sfiABsZDAAUEPj+Bvzr8gMA7vMG/QX77ufY9Pv38/n2+OrnAQDv5OPU6f8PDQX/GAb+7u0EBfPr8v0AJAr+7dnq7/b/G/TtAwvyDBMJ79Th1wAIAfDr/P/9DQAK6Ovi4AILEiMdGPP2/vv9BvkC+O8SDAULAwMXHP36C/kQCwENGgUKFAQSJRUABhsABQ0A+AklBeboDAMA8ejmAQEBFwQQEPsJ8wYJ9ejc7/0bDPDl+vICBgQJ/g3xAQMMEfQKDPP+7/oFBhscExD9Dff/8QALFfbwA/z7AxPx+fQLEwwNBBUWFCkEDAgB/+bz8AcH/On2Chb06vDzCAYLAA8iCQgF//77/PsCEhIKDxMwHg0C7e3s3uAF/fYIGPf0Fwj0/gHoFhH+/gwU/gIB6vbxEhn1FhARChgIABAC/gsZAube2vf45xHtAAP28foGBvfZ/AD4+grs/QL/3/D//Q31AwMW+uHo5/sYGf/3+wUkEAf6/Rwt6vYRAfn1EwwC8fz6EhP3AfMBGgD2CwwiGgUM9RAHCeLq8/T/+AMT7AUG8gYGCfrq4ukO+QMPFgj1DQsO8AL9/QLxAgP69PUKCQ4G7fz5DB0d9w8W/O/94drn+R0c+vj/+QoMGAj1Av4FH+fTz9nlAdTW6vQKHSEQBPLt9+jtAAT98uvi7+/h+PPV1tLp+PcOGAYE5ub2APnw5xwbHSwoGCT/CRn0+93b5fb6/Qb/Ehb19PYA9xcfHxIO/fr2DxEoGAAI//783t3sARTy6vH43sfO7gL27uj7GTcqGBsVEAYNEerl5PTyEx0RFv8VFwLv5gAIA/EdHSQWBPjpz8Ti9AsTDAcGHBkRAg4L+vH4DufdufD/DQcLHhsWJAXiAO7U3M/CByEdIAIA8v/x7vzo7/4A/QgG+PPw2+oDCBcvLiAK7Oj48u/x7wH/+AoQ9dnlDRoTIe0WKQsBDAYiKTIiAg3u/Anr3+Pr+/cDBRcCEhT33uEBBPHq5wwbBfsIBQ4bHQz/9uTl/BQF+AYI8e/V6wIFCA0yKAUG7+D07uze6fj65d3H/vbs5tG9/AQDBgb6+hsN9fPg3+n++fwbBBoLBSAlAgoLCw/vBBESEwANFiUxGvjmDBkaAQPl+hUD/wQC7RcCDx//CQokHOAREA8F3QQLEh4L8ePj3fkGBuLeDvPyDwYNAxYTFBv4/AIBAAT16PHo/gMKG/sJDRYW7/Tn9wMLCRgUGQYBAvrn/wD/Dv72AAEE7QX3/Q/t3BUP49Tl6fbt2vX03Nfi7hYbNC0NBPrQ1f369ebn/Pj27/zy/gYKChQNDwX+BQ8IBBIFBRcWFRP4AA4A/vv99QAP+gEXHg0bITIkEwgA8fIHBAcTIBz/7gD8BAD45d3rEBL/3O4GFhcOB/8AB/z+Ag0P7wQF+gQTDQsKExwQ+QcL//T8++bu8gsdJwQB8fT7BwP/9OLt+wUEDhULEx0nNyPxAvj89vX0CAAFBBMJDQUQ5tDg+PLauc/tAAQSFBH65QsRDQABHx8FAR8lIwv18OLk7/Dk4PcECgcADwv89vwnJ/ME+uLx8eID8/P56eLp+AIaMDojEu7v+vEFIw///goG9xAMDxgA9fjy7PT5Cuz1AAfxBB8vJgDp/gkRFuXyCRIOBQ0FA/v22NbS4wgYFA359QkO9esAAAQRGwMgGxoIqqjX+e/uCyIoDQL7BhIACg4qFvoTCLrd6fsLHxkTHBP+Ghf//cTX8v0RA+/z/wbk+OL7/xDQ1vUd+gD++v73Avb3+RsrJw7k8PsGCvwEDgIPBu8LD/sPIczk6vX7/w4EA/gZGQME8PX89/rq4/EFDQL0/PHjyfkL+Pb7//UcHSMlJ/vyFBIICv0J/vf7Dw8fCxoOCfwG/vTx/hj6+gYIDPn36e37BPwJBwcRDP/8AeTnEBwM/Qc9Ev0H+gMFAAUjLg8GA+bg7AAPEwX5+wwLHwn+/wIUEAj07u75AP7/EQn/9fTuERTo5dvr9vnl8vn/8gQzMAsP/u0IAvH4BwgGAQwT8AAC/hMHAwH69AMG9+/q6AT+BCATCvX2+vD94NX1+wEJB/r6D/oRGAkA+vj39PYC+/ED+wIXHQ4F6+DwCAvP4vr57vLr/AkA//L73ufq6AAeJAfUgoHyBvzqBQ8kIQ0VBvwVCwP/8vj09vT5CBse7O7n6+Lv4OLs6u/y3+X8Dgo6Ny8l4N3X4fXlydrr5gwcJSkTEhzx6P0K/gYUDAcOEA8IIycCBQrn08jr7BYY/uXvDh0dHQkKGP8AEvsGBRcLEQ7/+/r1+wDm4AIMBQ4HBuTm8ewA+gUWFi5HOSYgAwP7DBL/8ef+APj3+Oz/GCYpC/YHHBUGC/YDCvL6Bvz0G/UPFykdCBUbCgUACwwC/hMaHB4Y/ggUFQ7/D/wNBPcC9AHezAn/ARQHCf7y9PgIFPH+BAgGA+j1+/brAvzt6Lj39fcYBQgBDTApJgX5A/cFCBMIChUJBgX5C/77C/Hx8/7yBwf+BBH5A/zu4OHk7+zitbj+DRD78OwAEyQM+yIy/ur7+ufz+/8F+/35/P4MIw4E7gAlFgsCDAkPEQINF/sC/u3k3+r/BBL77BAS+gEBB/jpABLu5uf19/r8+PT8CwUFDfvrysDZ9vLm8wYVERP/6PD9AyEI+QYRDf//CeX19/4MFBUTDfz+Aun7+9jm+f3+AAH1+f39BvPrChQVBPAIERUL+/PTye4NCAb/9Pv+ECMMCwgL9Pz88wb9/goH+fPl8wUN/w4E+gUKDwQFKR8kBvkKCgD4/f74Dw71If0IAQQG+ufrCBMP8O78+uvw7eMG8PT/DBD68+8MGe/1+/X5/vgY/f7v7fABKRsH+gABDvvzDwjt9vj99/4GFAASGRcd9PX89QL6BgAG8g8ICvfz+gPz5fQDCQfz9g4YGBEF/gkECAjr8xgM+Q8ACBQU8fD3AAv7+eHf8/7y3+IEAh8TCfjw8u71/g0M/uXx8wYoMhH76NPr6/j2+u/+AvEB7v4HCwgZCwkrHysZBhAS+/v4/wz78gQkFg4I9e/Y6vv+8uTyD+36BAUP//sKFA4aMS8tCwH5Bx0S9fby/gEFC+Xh/AcTDf3++vcCFw0MBPsQAgMOCBMGChoPExfj4vL6FgMA+uX5AAP96Oz39uXp9QEECPnc+wUQCxLm7P0B6/Xv+ff0CTMuFwkHCRAnCPbhz+T8/+DT7PgUNyEXAP8P/AgI/+fu9wLo1972+vz/2e7y/PfS7QDz9+zw9vr8ERAK/RknCwbu6N75+QMODP732Mff8wL5C+Tq6xUiHQ8K/hEUEwwJAP8F/wP40+f+9/4E////6v8XD+nM4/Xx+BIKFgIIFw4HCenaAgr/GB4gCAcbKgX57wDP0+32Eg0B/v4OFgYE+wwA7N/y8vLt3N3tAiMO+/X8/g///PDp5+oC2AsP/PgYDx4o5v4QDiEEBysjEfoFFSkdB/4eJhECCfDg9A738fL3///4EhT4AA8bJAcC9xAZ4voFChL569jV5PsBBfXqA/QEDfXyAhYQDAsGDAka+A36HBAGEhUcGhH29vvs8+jo4Oz2/h4N/gDu7OT19vYB/vMB7vkVCQv++BEG+dne9f32BiUWBgAfITUsAA/l9gAMDhrT/vsLDxQV6O8M6xL5+ue55vH189np8P/ws+77//Hx8vIAEdfmBAn0GyTz+PYHEfn1+vPx/gcg9u0NAujl/fLV1+zR+QwVGgz/Cx0JF+/6C/H78wIL/Qrw/RHc4/fjvsfoAvkE4PX0BwUVDPgFISQK+O4ZHPkFBvocHxEkGSkMAvvc8w37/ff1AuPW/vH1/woNDwQYFxkUDfPfBfntBhr26vsHGhQLFOrz8v8L/vj5AvkF/gL//Pn2BvbrCv8O9vT6+/728gQDBxERCP8OFPv34/r/8+7d8Ov6Bu/5AfDl7QwDBBEVEAgDBwgLFA8LHwn6//jzAP33//L5/gb67wYGBO3m5/Hr/+kDBAEJEhIOEPr28PL4/P8G+/oLGjADCwX/Af/9AQkJ9/Ly/PwHCv0H/vH0/v0C9fL99xogFQ4YBQABAwr67/UWGQwIBAUQ+gQe4eb5DQMGDhQYDQcM/fL/8er8Bg/9/uvq9RkcIx4AAv4B/AwDAvUGFAkVGw4L5tnh6AEK+/r66vHq2NviAAUUGwX9+AYUGP0EAxAL8dTbBRX2/f4NFgwLDQv3FQ//+un/+AkXFAEE9PoCFQbc398OFxcPA/Ht1uzv/gHr9Pr68vXzAAYQAvr6CA7w+/wFDSDt+gT//PoIAQUR/e78Bg78+Oro7QMO9v4BBAH04M/lCwHt/wP0CAXX3fns7wMGEO8FDAkJ/u3izNr7+xMcBf32/f4a8t/29QH8AQTTBv0JKSYcBPDe8hX/CRfv/wkUAAnzBBUPAw/i6QgHGPLmFyQVCRcQ8/j2+fIKBv8FExwE8urnExoGICEQFf4j8ezs5foDAQIOEff/CMMXHfnu6dboCAL04eL5CNzO9BQJDxQKBwcZOxgREAs8KhMG3fPr9fv4+/sJAvopGvf88tTn+wvqBfrzAPLx5f4ECjk0DwbrAvcZAun2CvjxAwgHBAUIAeb29+wQD/r7AgMDCwgYHf4CAQoUHQwPxO8NBgfq9/UDAQL8/Pj0CQIQA/4aH+Px+/X19ePzBfTr6Pf8BwICCc7A7eP0+9DT7/ohFfEbCgsFAwL07/Px7gQXAfz4/v4XCRQLGx7+4AQYFvD/CBAA8/0XMy37Bv338g/37/T0/fH6HjUD8+8hGBUPASL57unsCBj5/AH13AXu9QfnBNztLCAQAvYiGxgS/xcgB/oHBCL6+QEWHhLyCAjc9OLy/PD97QAX9gMZ8uDt/eQEEvro+fQTEfb18xAaCOv+CRb3DQ0VFAz0+/TvB/oBFCYP9Qv+9u0FEBcP+PD9HAIL4/L39AsiE+vw1O4F/ObzEBn47fgEDPIG7wEJ/wfw5vf68wDxzvjT3egHJi8T/QkCA/T9CA8WCOP6BAj28vUCAvDq5wwcBvH+/QUH+Q3+9voPDRAVGxwW8fgN+wABExTl5wfu6u3vCx0gDAQTEu318w756vUN/gLqzuMEKh8B9PH6HhANB/sQBfoE+QUEASgkFwb5Ee0QERHt8P0KAxnoBgYMCvPxARD7AAMAERIaDwAIB/wP/AgFBP//BAsD7+T29fnp+gEE5vfn//rq9QIVA/nw7P4U6PIPEe3nDP34BQIVCv/45f7/CAL6CwQIIPr//gT07f/3BQP18gAVBO0L+An64gcRBQULB/n/5/cGFgnlpgwMDfXx/PMA5dDzFw4="},b:[-.48065,-.022214,-.14847,-.22966,-.19974,.52539,.98387,.59457,-.30747,-.076908,-.31714,.15821,.22441,-.237,.45228,-.10562,.186,-.15379,-.050172,.04386,1.1573,-.41681,.083819,-.24151,.28582,.54481,.79565,.068877,.45906,.10032,.17915,.3524]},conv3:{w:{shape:[32,32,3],scale:.012611277401447296,data_b64:"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"},b:[.17254,1.339,.4158,-.093339,.28021,-.046465,1.0513,.44342,1.0128,-.12751,-.87515,.64353,-.07254,1.0127,1.7885,1.6769,-.061762,.39241,-.26252,1.0561,.58258,-.23354,-.4736,.38796,.1319,.20964,.30156,1.8676,1.1334,-.093506,.71542,-.0054363]},conv4:{w:{shape:[32,32,3],scale:.021498816087841988,data_b64:"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"},b:[.039289,.34865,.95042,-.073607,1.4115,1.0756,.013808,.096819,.38295,.10098,-.18916,.169,2.1929,-.081778,.22036,.85779,-.44898,.21736,-.035547,.0096134,.7774,.22917,-.081477,.63055,.34935,1.9674,.54778,-.079256,.60878,.79962,.65425,1.9529]},bio:{w:{shape:[3,32],scale:.00724619859829545,data_b64:"/ugX9iQU9fzH9Qj7//n//VfnHw/rrPH+/xH4Kf72/gEB8RfuB/j8/Q33Bvvw/f71AX8BEgjz9gAE//kSBvn87fH1FwfQ4QX8R/YG+Q3+A/CstQgSJEHpAwcL++sI/PP1"},b:[.50217,-.69358,-.15374]},cls:{w:{shape:[120,32],scale:.010841965675354004,data_b64:"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"},b:[2.0176,.54879,-.74852,.6708,.39783,.50133,-.39469,.011433,.18709,-.17795,-.56959,-.41957,-.10239,-.20379,-.27652,-.23129,-.2993,-.59122,-.43887,-.21854,-.40505,-.32273,-.66862,-.36991,-.22728,-.015756,-.21333,-.54736,-.2546,-.30473,-.096751,-.33585,-.67811,-.60113,-.59227,-.50077,-.28001,-.62547,-.50637,-.69971,-.44887,-.24235,-.039837,-.17403,-.34016,-.16981,.053801,-.647,-.68176,-.50378,-.21779,-.19398,-.12628,-.28109,-.22943,-.36458,-.33458,-.32969,-.33054,-.06685,-.27666,-.30963,-.60442,-.47705,-.39358,-.18506,-.22168,-.31992,-.62064,-.49396,-.49137,-.29887,.056513,.083259,-.32745,-.43175,-.36524,-.56233,-.85284,-.53141,-.19461,-.032125,.18264,-.27448,.048796,-.115,-.469,-.25475,-.062195,-.099279,-.23322,-.62488,-.33195,-.25968,-.32699,-.27145,-.28322,-.063576,-.63915,-.14112,-.089139,-.66531,-.20493,-.27128,-.56956,-.4808,-.48607,-.45462,-.28481,-.36513,-.15753,-.65194,.28306,.072143,.026803,-.24859,.48548,-.0098499,.056588,-.34319]}};var Y=class{weights;charToId;gpu=null;defaultBackend;scratch;idsScratch=new Int32Array(M);bioIdsScratch=new Int32Array(128);clsIdsScratch=new Int32Array(128);bioProbsScratch=Array.from({length:128},()=>new Float32Array(3));constructor(e={}){this.weights=tA(e.weights??dA),this.charToId=sA(this.weights.charset),this.defaultBackend=e.backend??"cpu",this.scratch=new U(this.weights)}parse(e,n={}){let r=e;e=x(e);let f=r.length===e.length,t,s=oA(e.length);if(s.length===1&&s[0].length===e.length){let o=F(e.length),a=T(e,this.charToId,this.idsScratch,o),u=S(this.weights,a,this.scratch);t=this.decodeForward(e,u,0,e.length)}else{let o=[],a=new Set;for(let u of s){let c=e.slice(u.offset,u.offset+u.length),v=F(c.length),B=T(c,this.charToId,this.idsScratch,v),g=S(this.weights,B,this.scratch),D=this.decodeForward(c,g,u.offset,c.length);for(let i of D){let l=`${i.start}:${i.end}`;a.has(l)||(a.add(l),o.push(i))}}o.sort((u,c)=>u.start-c.start),t=o}if(f)for(let o of t)o.span=r.slice(o.start,o.end);return t}decodeForward(e,n,r,f=n.length){let t=f,s=t<=128,o=s?this.bioIdsScratch:new Int32Array(t),a=s?this.clsIdsScratch:new Int32Array(t),u=s?this.bioProbsScratch:Array.from({length:t},()=>new Float32Array(3));for(let B=0;B<t;B++)o[B]=J(n.bioLogits,B*3,3),a[B]=J(n.clsLogits,B*n.nCls,n.nCls),aA(n.bioLogits,B*3,3,u[B]);let c=CA(e,o.subarray(0,t),a.subarray(0,t),u),v=[];for(let B of c){let g=B.tokens.map(([l,I])=>[R[l],I]),D=wA(g),i=QA(e,B.start,B.end,te);v.push({span:B.text,start:B.start+r,end:B.end+r,value:D.value,...D.range?{range:D.range}:{},unit:D.unit??null,currency:i,confidence:B.confidence??0,classes:D.classes})}return v}async parseBatch(e,n={}){let r=n.backend??this.defaultBackend;if(!(r==="webgpu"||r==="auto"&&e.length>=32&&await Z()))return e.map(c=>this.parse(c,{backend:"cpu"}));let t=e,s=e.map(x),o=new Array(e.length),a=[],u=[];for(let c=0;c<s.length;c++)s[c].length<=128?a.push(c):u.push(c);for(let c of u)o[c]=this.parse(t[c],{backend:"cpu"});if(a.length>0){this.gpu||(this.gpu=new X(this.weights));let c=Math.max(...a.map(P=>s[P].length),1),v=F(c),B=a.length,g=new Int32Array(B*v),D=this.charToId.get("<pad>")??0;g.fill(D);for(let P=0;P<B;P++){let h=s[a[P]],d=T(h,this.charToId);g.set(d,P*v)}let{bio:i,cls:l}=await this.gpu.run(g,B,v),I=this.weights.cls.w.shape[0];for(let P=0;P<B;P++){let h=a[P],d=s[h],p=t[h],b=p.length===d.length,C=d.length,w=new Float32Array(C*3),Q=new Float32Array(C*I);for(let E=0;E<C;E++)w.set(i.subarray((P*v+E)*3,(P*v+E)*3+3),E*3),Q.set(l.subarray((P*v+E)*I,(P*v+E)*I+I),E*I);let H={bioLogits:w,clsLogits:Q,length:C,nCls:I},L=this.decodeForward(d,H,0,C);if(b)for(let E of L)E.span=p.slice(E.start,E.end);o[h]=L}}return o}},$=null;function IA(){return $||($=new Y),$}function pe(A,e={}){return IA().parse(A,e)}function Le(A,e={}){return IA().parseBatch(A,e)}function He(A={}){return new Y(A)}var te=lA(bA,EA);export{Y as Parser,He as createParser,q as isWebGPUAvailable,x as normalizeText,pe as parse,Le as parseBatch,Z as probeWebGPU};
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gpu-sankhya",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Fast char-CNN extraction of Hinglish
|
|
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",
|