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.
Files changed (54) hide show
  1. package/README.md +39 -0
  2. package/package.json +17 -5
  3. package/dist/cache.d.ts +0 -46
  4. package/dist/cache.d.ts.map +0 -1
  5. package/dist/cache.js +0 -160
  6. package/dist/cache.js.map +0 -1
  7. package/dist/device.d.ts +0 -86
  8. package/dist/device.d.ts.map +0 -1
  9. package/dist/device.js +0 -195
  10. package/dist/device.js.map +0 -1
  11. package/dist/gpu-recovery.d.ts +0 -61
  12. package/dist/gpu-recovery.d.ts.map +0 -1
  13. package/dist/gpu-recovery.js +0 -105
  14. package/dist/gpu-recovery.js.map +0 -1
  15. package/dist/hub.d.ts +0 -97
  16. package/dist/hub.d.ts.map +0 -1
  17. package/dist/hub.js +0 -142
  18. package/dist/hub.js.map +0 -1
  19. package/dist/index.d.ts +0 -61
  20. package/dist/index.d.ts.map +0 -1
  21. package/dist/index.js +0 -63
  22. package/dist/index.js.map +0 -1
  23. package/dist/inputs.d.ts +0 -27
  24. package/dist/inputs.d.ts.map +0 -1
  25. package/dist/inputs.js +0 -123
  26. package/dist/inputs.js.map +0 -1
  27. package/dist/loader.d.ts +0 -87
  28. package/dist/loader.d.ts.map +0 -1
  29. package/dist/loader.js +0 -156
  30. package/dist/loader.js.map +0 -1
  31. package/dist/model-client.d.ts +0 -149
  32. package/dist/model-client.d.ts.map +0 -1
  33. package/dist/model-client.js +0 -318
  34. package/dist/model-client.js.map +0 -1
  35. package/dist/model-worker.d.ts +0 -16
  36. package/dist/model-worker.d.ts.map +0 -1
  37. package/dist/model-worker.js +0 -340
  38. package/dist/model-worker.js.map +0 -1
  39. package/dist/onnx-pipeline.d.ts +0 -20
  40. package/dist/onnx-pipeline.d.ts.map +0 -1
  41. package/dist/onnx-pipeline.js +0 -385
  42. package/dist/onnx-pipeline.js.map +0 -1
  43. package/dist/pipelines/index.d.ts +0 -28
  44. package/dist/pipelines/index.d.ts.map +0 -1
  45. package/dist/pipelines/index.js +0 -134
  46. package/dist/pipelines/index.js.map +0 -1
  47. package/dist/streaming.d.ts +0 -55
  48. package/dist/streaming.d.ts.map +0 -1
  49. package/dist/streaming.js +0 -142
  50. package/dist/streaming.js.map +0 -1
  51. package/dist/types.d.ts +0 -196
  52. package/dist/types.d.ts.map +0 -1
  53. package/dist/types.js +0 -3
  54. 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.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.1.0",
50
- "onnxruntime-web": "^1.29.0"
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
@@ -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
@@ -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
@@ -1 +0,0 @@
1
- {"version":3,"file":"device.js","sourceRoot":"","sources":["../src/device.ts"],"names":[],"mappings":"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"}