webml-kit 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -0
- package/package.json +17 -5
- package/dist/cache.d.ts +0 -46
- package/dist/cache.d.ts.map +0 -1
- package/dist/cache.js +0 -160
- package/dist/cache.js.map +0 -1
- package/dist/device.d.ts +0 -86
- package/dist/device.d.ts.map +0 -1
- package/dist/device.js +0 -195
- package/dist/device.js.map +0 -1
- package/dist/gpu-recovery.d.ts +0 -61
- package/dist/gpu-recovery.d.ts.map +0 -1
- package/dist/gpu-recovery.js +0 -105
- package/dist/gpu-recovery.js.map +0 -1
- package/dist/hub.d.ts +0 -97
- package/dist/hub.d.ts.map +0 -1
- package/dist/hub.js +0 -142
- package/dist/hub.js.map +0 -1
- package/dist/index.d.ts +0 -61
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -63
- package/dist/index.js.map +0 -1
- package/dist/inputs.d.ts +0 -27
- package/dist/inputs.d.ts.map +0 -1
- package/dist/inputs.js +0 -123
- package/dist/inputs.js.map +0 -1
- package/dist/loader.d.ts +0 -87
- package/dist/loader.d.ts.map +0 -1
- package/dist/loader.js +0 -156
- package/dist/loader.js.map +0 -1
- package/dist/model-client.d.ts +0 -149
- package/dist/model-client.d.ts.map +0 -1
- package/dist/model-client.js +0 -318
- package/dist/model-client.js.map +0 -1
- package/dist/model-worker.d.ts +0 -16
- package/dist/model-worker.d.ts.map +0 -1
- package/dist/model-worker.js +0 -340
- package/dist/model-worker.js.map +0 -1
- package/dist/onnx-pipeline.d.ts +0 -20
- package/dist/onnx-pipeline.d.ts.map +0 -1
- package/dist/onnx-pipeline.js +0 -385
- package/dist/onnx-pipeline.js.map +0 -1
- package/dist/pipelines/index.d.ts +0 -28
- package/dist/pipelines/index.d.ts.map +0 -1
- package/dist/pipelines/index.js +0 -134
- package/dist/pipelines/index.js.map +0 -1
- package/dist/streaming.d.ts +0 -55
- package/dist/streaming.d.ts.map +0 -1
- package/dist/streaming.js +0 -142
- package/dist/streaming.js.map +0 -1
- package/dist/types.d.ts +0 -196
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -3
- package/dist/types.js.map +0 -1
package/README.md
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
> Framework-agnostic utilities for loading and running ML models in the browser via WebGPU/WASM.
|
|
8
8
|
|
|
9
|
+
**[Live Playground & Interactive Demos →](https://hemanth.github.io/webml-kit/)**
|
|
10
|
+
|
|
9
11
|
If you've ever built a browser-ML demo, you know the drill: copy 150 lines of Web Worker boilerplate from the last project, wire up `postMessage`, add progress reporting, handle the GPU vanishing mid-inference, and pray the model is cached so your user doesn't wait 3 minutes. Every. Single. Time.
|
|
10
12
|
|
|
11
13
|
This library does that part for you. It wraps [`@huggingface/transformers`](https://huggingface.co/docs/transformers.js) with a sane API and handles the ugly bits: device detection, model caching, token streaming, KV-cache management, and GPU recovery.
|
|
@@ -184,6 +186,43 @@ const asr = await webml('onnx-community/whisper-tiny.en'); // or any standalone
|
|
|
184
186
|
const { text } = await asr.transcribe(audioFloat32Array);
|
|
185
187
|
```
|
|
186
188
|
|
|
189
|
+
### Jev System One / OpenJev Decision Capabilities
|
|
190
|
+
|
|
191
|
+
Fast, calibrated, programmable decisions without autoregressive token generation. Turn natural language and application state into typed choices, binary verdicts (`noul`), or continuous level scores (`score`) with direct logit readouts:
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
import webml, { createDecisionEngine, directChoice } from 'webml-kit';
|
|
195
|
+
|
|
196
|
+
// One-shot direct choice
|
|
197
|
+
const result = await directChoice({
|
|
198
|
+
state: 'Customer reports: "My subscription charged twice, please refund immediately."',
|
|
199
|
+
question: 'Which department should handle this request?',
|
|
200
|
+
options: ['billing', 'technical-support', 'sales'],
|
|
201
|
+
});
|
|
202
|
+
console.log(result.choice); // 'billing'
|
|
203
|
+
console.log(result.confidence); // 0.88
|
|
204
|
+
console.log(result.probabilities); // { billing: 0.88, 'technical-support': 0.08, sales: 0.04 }
|
|
205
|
+
|
|
206
|
+
// Binary evaluation (Noul)
|
|
207
|
+
const engine = webml.decision({ model: 'qwen3-0.6b' });
|
|
208
|
+
const { noul, passed } = await engine.noul({
|
|
209
|
+
state: 'Production database cluster is reporting 500 errors',
|
|
210
|
+
statement: 'Is there an urgent incident?',
|
|
211
|
+
});
|
|
212
|
+
console.log(noul); // 0.94
|
|
213
|
+
console.log(passed); // true
|
|
214
|
+
|
|
215
|
+
// Continuous scoring along ordered criteria levels
|
|
216
|
+
const { score, confidence } = await engine.score({
|
|
217
|
+
state: 'There is a minor typo in the footer disclaimer.',
|
|
218
|
+
instructions: 'Rate issue severity',
|
|
219
|
+
criteria: ['P3', 'P2', 'P1', 'P0'],
|
|
220
|
+
});
|
|
221
|
+
console.log(score); // 0.15 (continuous score on 0-3 scale)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Supports OpenJev GGUF models (`minicpm5-2b`, `qwen3-0.6b`, `qwen3.5-4b`) via `@wllama/wllama` with WebGPU/WASM in browser and worker environments, with automatic, zero-dependency heuristic fallback for Node.js, offline, or test environments.
|
|
225
|
+
|
|
187
226
|
## API
|
|
188
227
|
|
|
189
228
|
### ModelClient
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webml-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Framework-agnostic utilities for loading and running ML models in the browser via WebGPU/WASM",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
"import": "./dist/index.js",
|
|
11
11
|
"types": "./dist/index.d.ts"
|
|
12
12
|
},
|
|
13
|
+
"./browser": {
|
|
14
|
+
"import": "./dist/webml-kit.browser.js",
|
|
15
|
+
"types": "./dist/index.d.ts"
|
|
16
|
+
},
|
|
13
17
|
"./worker": {
|
|
14
18
|
"import": "./dist/model-worker.js",
|
|
15
19
|
"types": "./dist/model-worker.d.ts"
|
|
@@ -21,10 +25,12 @@
|
|
|
21
25
|
"logo.png"
|
|
22
26
|
],
|
|
23
27
|
"scripts": {
|
|
24
|
-
"build": "tsc",
|
|
28
|
+
"build": "tsc && npm run build:browser",
|
|
29
|
+
"build:browser": "esbuild src/index.ts --bundle --format=esm --platform=browser --alias:onnxruntime-web=./src/shim-ort.ts --external:'node:*' --external:@huggingface/transformers --external:kokoro-js --external:@wllama/wllama --external:'@wllama/*' --outfile=dist/webml-kit.browser.js",
|
|
25
30
|
"dev": "tsc --watch",
|
|
26
31
|
"test": "vitest run",
|
|
27
32
|
"test:watch": "vitest",
|
|
33
|
+
"test:e2e": "node test/e2e-playground.mjs",
|
|
28
34
|
"clean": "rm -rf dist",
|
|
29
35
|
"prepublishOnly": "npm run clean && npm run build"
|
|
30
36
|
},
|
|
@@ -43,15 +49,21 @@
|
|
|
43
49
|
"license": "MIT",
|
|
44
50
|
"repository": {
|
|
45
51
|
"type": "git",
|
|
46
|
-
"url": "https://github.com/hemanth/webml-kit.git"
|
|
52
|
+
"url": "git+https://github.com/hemanth/webml-kit.git"
|
|
47
53
|
},
|
|
48
54
|
"dependencies": {
|
|
49
|
-
"@huggingface/transformers": "^4.
|
|
50
|
-
"
|
|
55
|
+
"@huggingface/transformers": "^4.3.0",
|
|
56
|
+
"kokoro-js": "^1.2.1",
|
|
57
|
+
"onnxruntime-web": "^1.30.0"
|
|
51
58
|
},
|
|
52
59
|
"devDependencies": {
|
|
53
60
|
"@webgpu/types": "^0.1.69",
|
|
61
|
+
"esbuild": "^0.28.2",
|
|
62
|
+
"playwright": "^1.63.0",
|
|
54
63
|
"typescript": "^5.7.0",
|
|
55
64
|
"vitest": "^4.1.4"
|
|
65
|
+
},
|
|
66
|
+
"optionalDependencies": {
|
|
67
|
+
"@wllama/wllama": "^3.6.1"
|
|
56
68
|
}
|
|
57
69
|
}
|
package/dist/cache.d.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Model cache visibility utilities.
|
|
3
|
-
*
|
|
4
|
-
* Transformers.js uses the Cache API internally to persist downloaded model
|
|
5
|
-
* files. This module gives users visibility into what's cached, letting them
|
|
6
|
-
* skip "downloading…" UX for returning users or clear storage on mobile.
|
|
7
|
-
*/
|
|
8
|
-
import type { CachedModel, CacheBackend } from './types.js';
|
|
9
|
-
/**
|
|
10
|
-
* Detect which cache backend is available.
|
|
11
|
-
* Priority: Cache API → OPFS → IndexedDB
|
|
12
|
-
*/
|
|
13
|
-
export declare function getCacheBackend(): Promise<CacheBackend>;
|
|
14
|
-
/**
|
|
15
|
-
* Check if a specific model is already cached locally.
|
|
16
|
-
*
|
|
17
|
-
* ```ts
|
|
18
|
-
* if (await isCached('onnx-community/Bonsai-1.7B-ONNX')) {
|
|
19
|
-
* // Skip "downloading..." UI
|
|
20
|
-
* }
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
export declare function isCached(modelId: string): Promise<boolean>;
|
|
24
|
-
/**
|
|
25
|
-
* Get total cache size in bytes used by downloaded models.
|
|
26
|
-
*/
|
|
27
|
-
export declare function getCacheSize(): Promise<number>;
|
|
28
|
-
/**
|
|
29
|
-
* List all cached models with metadata.
|
|
30
|
-
*/
|
|
31
|
-
export declare function listCachedModels(): Promise<CachedModel[]>;
|
|
32
|
-
/**
|
|
33
|
-
* Clear cached model files.
|
|
34
|
-
*
|
|
35
|
-
* @param modelId - Specific model to clear, or omit to clear all.
|
|
36
|
-
*
|
|
37
|
-
* ```ts
|
|
38
|
-
* // Clear a specific model
|
|
39
|
-
* await clearCache('onnx-community/Bonsai-1.7B-ONNX');
|
|
40
|
-
*
|
|
41
|
-
* // Clear all cached models
|
|
42
|
-
* await clearCache();
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
export declare function clearCache(modelId?: string): Promise<void>;
|
|
46
|
-
//# sourceMappingURL=cache.d.ts.map
|
package/dist/cache.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM5D;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC,CAmB7D;AAED;;;;;;;;GAQG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAoBhE;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CASpD;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CA4C/D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BhE"}
|
package/dist/cache.js
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Model cache visibility utilities.
|
|
3
|
-
*
|
|
4
|
-
* Transformers.js uses the Cache API internally to persist downloaded model
|
|
5
|
-
* files. This module gives users visibility into what's cached, letting them
|
|
6
|
-
* skip "downloading…" UX for returning users or clear storage on mobile.
|
|
7
|
-
*/
|
|
8
|
-
import { formatSize } from './device.js';
|
|
9
|
-
/** HuggingFace Transformers.js cache name prefix */
|
|
10
|
-
const HF_CACHE_PREFIX = 'transformers-cache';
|
|
11
|
-
/**
|
|
12
|
-
* Detect which cache backend is available.
|
|
13
|
-
* Priority: Cache API → OPFS → IndexedDB
|
|
14
|
-
*/
|
|
15
|
-
export async function getCacheBackend() {
|
|
16
|
-
if (typeof caches !== 'undefined') {
|
|
17
|
-
return 'cache-api';
|
|
18
|
-
}
|
|
19
|
-
if (typeof navigator !== 'undefined' && 'storage' in navigator) {
|
|
20
|
-
try {
|
|
21
|
-
const root = await navigator.storage.getDirectory();
|
|
22
|
-
if (root)
|
|
23
|
-
return 'opfs';
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
// OPFS not available
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
if (typeof indexedDB !== 'undefined') {
|
|
30
|
-
return 'indexeddb';
|
|
31
|
-
}
|
|
32
|
-
return 'cache-api'; // fallback, will fail gracefully
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Check if a specific model is already cached locally.
|
|
36
|
-
*
|
|
37
|
-
* ```ts
|
|
38
|
-
* if (await isCached('onnx-community/Bonsai-1.7B-ONNX')) {
|
|
39
|
-
* // Skip "downloading..." UI
|
|
40
|
-
* }
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
export async function isCached(modelId) {
|
|
44
|
-
if (typeof caches === 'undefined')
|
|
45
|
-
return false;
|
|
46
|
-
try {
|
|
47
|
-
const keys = await caches.keys();
|
|
48
|
-
const hfCaches = keys.filter(k => k.startsWith(HF_CACHE_PREFIX));
|
|
49
|
-
for (const cacheName of hfCaches) {
|
|
50
|
-
const cache = await caches.open(cacheName);
|
|
51
|
-
const cacheKeys = await cache.keys();
|
|
52
|
-
const hasModel = cacheKeys.some(req => req.url.includes(encodeURIComponent(modelId)) || req.url.includes(modelId));
|
|
53
|
-
if (hasModel)
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
// Cache API not available or permission denied
|
|
59
|
-
}
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Get total cache size in bytes used by downloaded models.
|
|
64
|
-
*/
|
|
65
|
-
export async function getCacheSize() {
|
|
66
|
-
if (typeof navigator === 'undefined' || !('storage' in navigator))
|
|
67
|
-
return 0;
|
|
68
|
-
try {
|
|
69
|
-
const estimate = await navigator.storage.estimate();
|
|
70
|
-
return estimate.usage ?? 0;
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
return 0;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* List all cached models with metadata.
|
|
78
|
-
*/
|
|
79
|
-
export async function listCachedModels() {
|
|
80
|
-
if (typeof caches === 'undefined')
|
|
81
|
-
return [];
|
|
82
|
-
const models = [];
|
|
83
|
-
try {
|
|
84
|
-
const keys = await caches.keys();
|
|
85
|
-
const hfCaches = keys.filter(k => k.startsWith(HF_CACHE_PREFIX));
|
|
86
|
-
for (const cacheName of hfCaches) {
|
|
87
|
-
const cache = await caches.open(cacheName);
|
|
88
|
-
const cacheKeys = await cache.keys();
|
|
89
|
-
// Group by model ID (extract from URL pattern)
|
|
90
|
-
const modelUrls = new Map();
|
|
91
|
-
for (const request of cacheKeys) {
|
|
92
|
-
const url = request.url;
|
|
93
|
-
// HF URLs: https://huggingface.co/{org}/{model}/resolve/{rev}/{file}
|
|
94
|
-
const match = url.match(/huggingface\.co\/([^/]+\/[^/]+)\//);
|
|
95
|
-
if (match) {
|
|
96
|
-
const id = match[1];
|
|
97
|
-
const response = await cache.match(request);
|
|
98
|
-
const size = response
|
|
99
|
-
? Number(response.headers.get('content-length') ?? 0)
|
|
100
|
-
: 0;
|
|
101
|
-
modelUrls.set(id, (modelUrls.get(id) ?? 0) + size);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
for (const [modelId, sizeBytes] of modelUrls) {
|
|
105
|
-
models.push({
|
|
106
|
-
modelId,
|
|
107
|
-
sizeBytes,
|
|
108
|
-
size: formatSize(sizeBytes),
|
|
109
|
-
lastAccessed: new Date(), // Cache API doesn't track this
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
catch {
|
|
115
|
-
// Cache API not available
|
|
116
|
-
}
|
|
117
|
-
return models;
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Clear cached model files.
|
|
121
|
-
*
|
|
122
|
-
* @param modelId - Specific model to clear, or omit to clear all.
|
|
123
|
-
*
|
|
124
|
-
* ```ts
|
|
125
|
-
* // Clear a specific model
|
|
126
|
-
* await clearCache('onnx-community/Bonsai-1.7B-ONNX');
|
|
127
|
-
*
|
|
128
|
-
* // Clear all cached models
|
|
129
|
-
* await clearCache();
|
|
130
|
-
* ```
|
|
131
|
-
*/
|
|
132
|
-
export async function clearCache(modelId) {
|
|
133
|
-
if (typeof caches === 'undefined')
|
|
134
|
-
return;
|
|
135
|
-
try {
|
|
136
|
-
const keys = await caches.keys();
|
|
137
|
-
const hfCaches = keys.filter(k => k.startsWith(HF_CACHE_PREFIX));
|
|
138
|
-
for (const cacheName of hfCaches) {
|
|
139
|
-
if (!modelId) {
|
|
140
|
-
// Clear entire cache
|
|
141
|
-
await caches.delete(cacheName);
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
// Clear specific model
|
|
145
|
-
const cache = await caches.open(cacheName);
|
|
146
|
-
const cacheKeys = await cache.keys();
|
|
147
|
-
for (const request of cacheKeys) {
|
|
148
|
-
if (request.url.includes(encodeURIComponent(modelId)) ||
|
|
149
|
-
request.url.includes(modelId)) {
|
|
150
|
-
await cache.delete(request);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
catch {
|
|
157
|
-
// Cache API not available
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
//# sourceMappingURL=cache.js.map
|
package/dist/cache.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
|
package/dist/device.d.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WebGPU / WASM device detection and capability probing.
|
|
3
|
-
*
|
|
4
|
-
* Detects the best available backend, extracts GPU adapter info,
|
|
5
|
-
* and recommends a quantization level based on estimated VRAM.
|
|
6
|
-
*/
|
|
7
|
-
import type { DeviceBackend, DeviceInfo, GPUInfo, QuantizationType } from './types.js';
|
|
8
|
-
/**
|
|
9
|
-
* Check if WebGPU is available and request an adapter.
|
|
10
|
-
* Returns `null` if WebGPU is not supported.
|
|
11
|
-
*/
|
|
12
|
-
export declare function getGPUAdapter(): Promise<GPUAdapter | null>;
|
|
13
|
-
/**
|
|
14
|
-
* Extract GPU info from an adapter.
|
|
15
|
-
*/
|
|
16
|
-
export declare function getGPUInfo(adapter: GPUAdapter): Promise<GPUInfo>;
|
|
17
|
-
/**
|
|
18
|
-
* Recommend a quantization dtype based on available VRAM.
|
|
19
|
-
*/
|
|
20
|
-
export declare function recommendDtype(vram: number): QuantizationType;
|
|
21
|
-
/**
|
|
22
|
-
* Check if WebGPU is available.
|
|
23
|
-
*/
|
|
24
|
-
export declare function checkWebGPU(): Promise<boolean>;
|
|
25
|
-
/**
|
|
26
|
-
* Check if WebAssembly is available.
|
|
27
|
-
*/
|
|
28
|
-
export declare function checkWASM(): boolean;
|
|
29
|
-
/**
|
|
30
|
-
* Detect the best available compute backend and return device info.
|
|
31
|
-
*
|
|
32
|
-
* Priority: WebGPU → WASM → CPU
|
|
33
|
-
*
|
|
34
|
-
* ```ts
|
|
35
|
-
* const info = await detectDevice();
|
|
36
|
-
* console.log(info.backend); // 'webgpu'
|
|
37
|
-
* console.log(info.recommendedDtype); // 'q4'
|
|
38
|
-
* console.log(info.gpu?.vendor); // 'apple'
|
|
39
|
-
* ```
|
|
40
|
-
*/
|
|
41
|
-
export declare function detectDevice(): Promise<DeviceInfo>;
|
|
42
|
-
/**
|
|
43
|
-
* Parse a human-readable size string into bytes.
|
|
44
|
-
*
|
|
45
|
-
* Accepts formats like '4GB', '512 MB', '1.5gb', '256mb'.
|
|
46
|
-
* Also accepts raw numbers (passed through as-is).
|
|
47
|
-
*
|
|
48
|
-
* ```ts
|
|
49
|
-
* parseSize('4GB') // 4294967296
|
|
50
|
-
* parseSize('512MB') // 536870912
|
|
51
|
-
* parseSize('1.5gb') // 1610612736
|
|
52
|
-
* parseSize(1024) // 1024
|
|
53
|
-
* ```
|
|
54
|
-
*/
|
|
55
|
-
export declare function parseSize(input: string | number): number;
|
|
56
|
-
/**
|
|
57
|
-
* Format bytes into a human-readable string.
|
|
58
|
-
*
|
|
59
|
-
* ```ts
|
|
60
|
-
* formatSize(4294967296) // '4 GB'
|
|
61
|
-
* formatSize(536870912) // '512 MB'
|
|
62
|
-
* formatSize(1536) // '1.5 KB'
|
|
63
|
-
* ```
|
|
64
|
-
*/
|
|
65
|
-
export declare function formatSize(bytes: number): string;
|
|
66
|
-
/**
|
|
67
|
-
* Check whether a model of a given size can likely run
|
|
68
|
-
* on the current device without OOM.
|
|
69
|
-
*
|
|
70
|
-
* Accepts human-readable strings or raw byte counts:
|
|
71
|
-
*
|
|
72
|
-
* ```ts
|
|
73
|
-
* await canRun('4GB');
|
|
74
|
-
* await canRun('512MB');
|
|
75
|
-
* await canRun(4_000_000_000);
|
|
76
|
-
* ```
|
|
77
|
-
*
|
|
78
|
-
* This is a heuristic — real limits depend on browser, OS, and
|
|
79
|
-
* other tabs consuming VRAM.
|
|
80
|
-
*/
|
|
81
|
-
export declare function canRun(estimatedSize: string | number): Promise<{
|
|
82
|
-
ok: boolean;
|
|
83
|
-
backend: DeviceBackend;
|
|
84
|
-
reason?: string;
|
|
85
|
-
}>;
|
|
86
|
-
//# sourceMappingURL=device.d.ts.map
|
package/dist/device.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../src/device.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAWvF;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAYhE;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAetE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAK7D;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAGpD;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC,CA2BxD;AAYD;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAaxD;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMhD;AAID;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,MAAM,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACpE,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAiBD"}
|
package/dist/device.js
DELETED
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WebGPU / WASM device detection and capability probing.
|
|
3
|
-
*
|
|
4
|
-
* Detects the best available backend, extracts GPU adapter info,
|
|
5
|
-
* and recommends a quantization level based on estimated VRAM.
|
|
6
|
-
*/
|
|
7
|
-
// ─── VRAM thresholds for dtype recommendation ───
|
|
8
|
-
const VRAM_THRESHOLDS = [
|
|
9
|
-
{ min: 8 * 1024 ** 3, dtype: 'fp16' }, // 8 GB+ → fp16
|
|
10
|
-
{ min: 4 * 1024 ** 3, dtype: 'q8' }, // 4 GB+ → q8
|
|
11
|
-
{ min: 2 * 1024 ** 3, dtype: 'q4' }, // 2 GB+ → q4
|
|
12
|
-
{ min: 0, dtype: 'q4' }, // < 2 GB → q4 (safest)
|
|
13
|
-
];
|
|
14
|
-
/**
|
|
15
|
-
* Check if WebGPU is available and request an adapter.
|
|
16
|
-
* Returns `null` if WebGPU is not supported.
|
|
17
|
-
*/
|
|
18
|
-
export async function getGPUAdapter() {
|
|
19
|
-
if (typeof navigator === 'undefined')
|
|
20
|
-
return null;
|
|
21
|
-
if (!('gpu' in navigator))
|
|
22
|
-
return null;
|
|
23
|
-
try {
|
|
24
|
-
const adapter = await navigator.gpu.requestAdapter({
|
|
25
|
-
powerPreference: 'high-performance',
|
|
26
|
-
});
|
|
27
|
-
return adapter;
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Extract GPU info from an adapter.
|
|
35
|
-
*/
|
|
36
|
-
export async function getGPUInfo(adapter) {
|
|
37
|
-
// adapterInfo is available synchronously on modern browsers
|
|
38
|
-
const info = adapter.info ?? adapter.requestAdapterInfo?.();
|
|
39
|
-
const resolved = info instanceof Promise ? await info : info;
|
|
40
|
-
// maxBufferSize gives a rough VRAM lower-bound
|
|
41
|
-
const vram = Number(adapter.limits?.maxBufferSize ?? 0);
|
|
42
|
-
return {
|
|
43
|
-
vendor: resolved?.vendor ?? 'unknown',
|
|
44
|
-
architecture: resolved?.architecture ?? 'unknown',
|
|
45
|
-
description: resolved?.description ?? 'unknown',
|
|
46
|
-
vram,
|
|
47
|
-
vramFormatted: formatSize(vram),
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Recommend a quantization dtype based on available VRAM.
|
|
52
|
-
*/
|
|
53
|
-
export function recommendDtype(vram) {
|
|
54
|
-
for (const { min, dtype } of VRAM_THRESHOLDS) {
|
|
55
|
-
if (vram >= min)
|
|
56
|
-
return dtype;
|
|
57
|
-
}
|
|
58
|
-
return 'q4';
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Check if WebGPU is available.
|
|
62
|
-
*/
|
|
63
|
-
export async function checkWebGPU() {
|
|
64
|
-
const adapter = await getGPUAdapter();
|
|
65
|
-
return adapter !== null;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Check if WebAssembly is available.
|
|
69
|
-
*/
|
|
70
|
-
export function checkWASM() {
|
|
71
|
-
return typeof WebAssembly !== 'undefined';
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Detect the best available compute backend and return device info.
|
|
75
|
-
*
|
|
76
|
-
* Priority: WebGPU → WASM → CPU
|
|
77
|
-
*
|
|
78
|
-
* ```ts
|
|
79
|
-
* const info = await detectDevice();
|
|
80
|
-
* console.log(info.backend); // 'webgpu'
|
|
81
|
-
* console.log(info.recommendedDtype); // 'q4'
|
|
82
|
-
* console.log(info.gpu?.vendor); // 'apple'
|
|
83
|
-
* ```
|
|
84
|
-
*/
|
|
85
|
-
export async function detectDevice() {
|
|
86
|
-
// Try WebGPU first
|
|
87
|
-
const adapter = await getGPUAdapter();
|
|
88
|
-
if (adapter) {
|
|
89
|
-
const gpu = await getGPUInfo(adapter);
|
|
90
|
-
return {
|
|
91
|
-
backend: 'webgpu',
|
|
92
|
-
gpu,
|
|
93
|
-
recommendedDtype: recommendDtype(gpu.vram),
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
// Fall back to WASM
|
|
97
|
-
if (checkWASM()) {
|
|
98
|
-
return {
|
|
99
|
-
backend: 'wasm',
|
|
100
|
-
gpu: null,
|
|
101
|
-
recommendedDtype: 'q4',
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
// CPU-only (rare)
|
|
105
|
-
return {
|
|
106
|
-
backend: 'cpu',
|
|
107
|
-
gpu: null,
|
|
108
|
-
recommendedDtype: 'q4',
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
// ─── Size parsing / formatting ───
|
|
112
|
-
const SIZE_UNITS = {
|
|
113
|
-
b: 1,
|
|
114
|
-
kb: 1024,
|
|
115
|
-
mb: 1024 ** 2,
|
|
116
|
-
gb: 1024 ** 3,
|
|
117
|
-
tb: 1024 ** 4,
|
|
118
|
-
};
|
|
119
|
-
/**
|
|
120
|
-
* Parse a human-readable size string into bytes.
|
|
121
|
-
*
|
|
122
|
-
* Accepts formats like '4GB', '512 MB', '1.5gb', '256mb'.
|
|
123
|
-
* Also accepts raw numbers (passed through as-is).
|
|
124
|
-
*
|
|
125
|
-
* ```ts
|
|
126
|
-
* parseSize('4GB') // 4294967296
|
|
127
|
-
* parseSize('512MB') // 536870912
|
|
128
|
-
* parseSize('1.5gb') // 1610612736
|
|
129
|
-
* parseSize(1024) // 1024
|
|
130
|
-
* ```
|
|
131
|
-
*/
|
|
132
|
-
export function parseSize(input) {
|
|
133
|
-
if (typeof input === 'number')
|
|
134
|
-
return input;
|
|
135
|
-
const match = input.trim().match(/^([\d.]+)\s*(b|kb|mb|gb|tb)$/i);
|
|
136
|
-
if (!match) {
|
|
137
|
-
throw new Error(`Invalid size format: "${input}". Use something like "4GB", "512MB", or a number in bytes.`);
|
|
138
|
-
}
|
|
139
|
-
const value = parseFloat(match[1]);
|
|
140
|
-
const unit = match[2].toLowerCase();
|
|
141
|
-
return Math.round(value * SIZE_UNITS[unit]);
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Format bytes into a human-readable string.
|
|
145
|
-
*
|
|
146
|
-
* ```ts
|
|
147
|
-
* formatSize(4294967296) // '4 GB'
|
|
148
|
-
* formatSize(536870912) // '512 MB'
|
|
149
|
-
* formatSize(1536) // '1.5 KB'
|
|
150
|
-
* ```
|
|
151
|
-
*/
|
|
152
|
-
export function formatSize(bytes) {
|
|
153
|
-
if (bytes >= 1024 ** 4)
|
|
154
|
-
return `${(bytes / 1024 ** 4).toFixed(1)} TB`;
|
|
155
|
-
if (bytes >= 1024 ** 3)
|
|
156
|
-
return `${(bytes / 1024 ** 3).toFixed(1)} GB`;
|
|
157
|
-
if (bytes >= 1024 ** 2)
|
|
158
|
-
return `${(bytes / 1024 ** 2).toFixed(1)} MB`;
|
|
159
|
-
if (bytes >= 1024)
|
|
160
|
-
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
161
|
-
return `${bytes} B`;
|
|
162
|
-
}
|
|
163
|
-
// ─── canRun ───
|
|
164
|
-
/**
|
|
165
|
-
* Check whether a model of a given size can likely run
|
|
166
|
-
* on the current device without OOM.
|
|
167
|
-
*
|
|
168
|
-
* Accepts human-readable strings or raw byte counts:
|
|
169
|
-
*
|
|
170
|
-
* ```ts
|
|
171
|
-
* await canRun('4GB');
|
|
172
|
-
* await canRun('512MB');
|
|
173
|
-
* await canRun(4_000_000_000);
|
|
174
|
-
* ```
|
|
175
|
-
*
|
|
176
|
-
* This is a heuristic — real limits depend on browser, OS, and
|
|
177
|
-
* other tabs consuming VRAM.
|
|
178
|
-
*/
|
|
179
|
-
export async function canRun(estimatedSize) {
|
|
180
|
-
const bytes = parseSize(estimatedSize);
|
|
181
|
-
const device = await detectDevice();
|
|
182
|
-
if (device.backend === 'webgpu' && device.gpu) {
|
|
183
|
-
// Leave ~500MB headroom for browser internals
|
|
184
|
-
const available = device.gpu.vram - 512 * 1024 ** 2;
|
|
185
|
-
if (bytes > available) {
|
|
186
|
-
return {
|
|
187
|
-
ok: false,
|
|
188
|
-
backend: device.backend,
|
|
189
|
-
reason: `Model (~${formatSize(bytes)}) exceeds available VRAM (~${formatSize(available)})`,
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
return { ok: true, backend: device.backend };
|
|
194
|
-
}
|
|
195
|
-
//# sourceMappingURL=device.js.map
|
package/dist/device.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"device.js","sourceRoot":"","sources":["../src/device.ts"],"names":[],"mappings":"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"}
|