edgeinfer 0.0.0-stage → 2.0.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/LICENSE +21 -0
- package/README.md +363 -2
- package/dist/index.d.mts +590 -0
- package/dist/index.d.ts +590 -0
- package/dist/index.js +1827 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1769 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +62 -4
- package/src/download.ts +39 -0
- package/src/edgeinfer.ts +710 -0
- package/src/events.ts +17 -0
- package/src/image-processor.ts +35 -0
- package/src/index.ts +15 -0
- package/src/matryoshka.ts +441 -0
- package/src/model-cache.ts +46 -0
- package/src/onnx-lm.ts +104 -0
- package/src/runtime-manager.ts +338 -0
- package/src/speculative.ts +294 -0
- package/src/tokenizer.ts +419 -0
- package/src/types.ts +19 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/events.ts","../src/download.ts","../src/model-cache.ts","../src/runtime-manager.ts","../src/tokenizer.ts","../src/image-processor.ts","../src/edgeinfer.ts","../src/matryoshka.ts","../src/speculative.ts","../src/onnx-lm.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n// Copyright (c) 2024-2026 Soumya Debnath\n\nexport * from './types';\nexport * from './events';\nexport * from './model-cache';\nexport * from './runtime-manager';\nexport * from './tokenizer';\nexport * from './image-processor';\nexport * from './edgeinfer';\n\nexport type { DownloadOptions } from './download';\nexport * from './matryoshka';\nexport * from './speculative';\nexport * from './onnx-lm';\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2024-2026 Soumya Debnath\n\nexport class EventEmitter {\n private listeners: Record<string, Function[]> = {};\n\n on(event: string, callback: Function) {\n if (!this.listeners[event]) this.listeners[event] = [];\n this.listeners[event].push(callback);\n }\n\n emit(event: string, ...args: any[]) {\n if (this.listeners[event]) {\n this.listeners[event].forEach(cb => cb(...args));\n }\n }\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2024-2026 Soumya Debnath\n\n/** Per-transfer options; covers response headers and the entire response body. */\nexport interface DownloadOptions {\n signal?: AbortSignal;\n /** Default 120 seconds per model/tokenizer transfer, not an inference timeout. */\n downloadTimeoutMs?: number;\n}\n\n/** Compatible with AbortController implementations without throwIfAborted. */\nexport function checkDownloadAbort(signal?: AbortSignal): void {\n if (signal?.aborted) throw signal.reason ?? new DOMException('Download aborted', 'AbortError');\n}\n\nexport async function withDownloadDeadline<T>(operation: (signal: AbortSignal) => Promise<T>, options: DownloadOptions = {}): Promise<T> {\n const timeout = options.downloadTimeoutMs ?? 120000;\n if (!Number.isFinite(timeout) || timeout <= 0 || timeout > 2147483647) {\n throw new RangeError('downloadTimeoutMs must be between 0 and 2147483647 milliseconds');\n }\n const controller = new AbortController();\n const abort = () => controller.abort(options.signal?.reason);\n if (options.signal?.aborted) abort();\n else options.signal?.addEventListener('abort', abort, { once: true });\n const timer = setTimeout(() => controller.abort(new DOMException('Download deadline exceeded', 'TimeoutError')), timeout);\n let onAbort: () => void = () => {};\n try {\n checkDownloadAbort(controller.signal);\n const cancelled = new Promise<never>((_, reject) => {\n onAbort = () => reject(controller.signal.reason ?? new DOMException('Download aborted', 'AbortError'));\n controller.signal.addEventListener('abort', onAbort, { once: true });\n });\n return await Promise.race([operation(controller.signal), cancelled]);\n } finally {\n clearTimeout(timer);\n controller.signal.removeEventListener('abort', onAbort);\n options.signal?.removeEventListener('abort', abort);\n }\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2024-2026 Soumya Debnath\n\nimport { EventEmitter } from './events';\nimport { withDownloadDeadline, DownloadOptions, checkDownloadAbort } from './download';\n\nexport class ModelCache extends EventEmitter {\n private cacheName: string;\n\n constructor(cacheName: string = 'edgeinfer-models') {\n super();\n this.cacheName = cacheName;\n }\n\n async getModel(url: string, forceDownload: boolean = false, options: DownloadOptions = {}): Promise<ArrayBuffer> {\n return withDownloadDeadline(async signal => {\n const cache = typeof caches === 'undefined' ? undefined : await caches.open(this.cacheName);\n checkDownloadAbort(signal);\n const cached = !forceDownload && cache ? await cache.match(url) : undefined;\n checkDownloadAbort(signal);\n if (cached) {\n const buffer = await cached.arrayBuffer();\n checkDownloadAbort(signal);\n return buffer;\n }\n this.emit('downloadStart', url);\n checkDownloadAbort(signal);\n const response = await fetch(url, { signal });\n if (!response.ok) {\n await response.body?.cancel();\n throw new Error(`EdgeInfer: failed to fetch model from ${url} - HTTP ${response.status} ${response.statusText}`);\n }\n if (response.status === 206 || response.headers.has('content-range')) {\n await response.body?.cancel();\n throw new Error('EdgeInfer: partial model responses are not supported');\n }\n // Read completely before committing, so aborted/truncated bodies cannot be cached.\n const buffer = await response.arrayBuffer();\n checkDownloadAbort(signal);\n if (cache) await cache.put(url, new Response(buffer, { headers: response.headers }));\n checkDownloadAbort(signal);\n this.emit('downloadComplete', url);\n return buffer;\n }, options);\n }\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2024-2026 Soumya Debnath\n\nimport * as ort from 'onnxruntime-web';\n\nexport interface VRAMProbeResult {\n available: boolean;\n /** Largest single storage buffer the device actually allocated. */\n maxAllocationBytes: number;\n testedAllocations: number[];\n failedAllocationBytes: number | null;\n adapterLimits: {\n maxBufferSize: number;\n maxStorageBufferBindingSize: number;\n };\n deviceCreated: boolean;\n probe: 'empirical' | 'limits' | 'unavailable';\n}\n\nexport interface VRAMProbeOptions {\n startBytes?: number;\n maxBytes?: number;\n stepBytes?: number;\n}\n\nexport interface GPUCapabilities {\n provider: string;\n hasWebGPU: boolean;\n hasWebNN: boolean;\n /**\n * NOT an amount of video memory. This is the largest single GPU storage\n * buffer allocated by the empirical probe, bounded by the adapter's\n * `maxBufferSize`. Browser baselines are commonly 256 MiB regardless of the\n * physical card, so treat this as a maximum-tensor-size budget, not as VRAM.\n */\n estimatedVRAM: number;\n /** Raw adapter limits, kept separate from the empirical probe. */\n adapterLimits: {\n maxBufferSize: number;\n maxStorageBufferBindingSize: number;\n } | null;\n /** Evidence for how `estimatedVRAM` was obtained. */\n vramProbe: VRAMProbeResult | null;\n recommendedQuantization: 'fp32' | 'fp16' | 'int8' | 'int4';\n}\n\n/** Max time to wait for navigator.gpu.requestAdapter() before giving up. */\nconst ADAPTER_TIMEOUT_MS = 5000;\n\n/**\n * RuntimeManager handles execution provider detection and ONNX session creation.\n * Implements a smart fallback chain: WebGPU → WebNN → WASM\n * with automatic quantization level recommendation based on available GPU memory.\n */\nexport class RuntimeManager {\n private static cachedCapabilities: GPUCapabilities | null = null;\n\n /**\n * Detect GPU capabilities and recommend the best execution configuration.\n */\n static async detectCapabilities(): Promise<GPUCapabilities> {\n if (this.cachedCapabilities) return this.cachedCapabilities;\n\n const capabilities: GPUCapabilities = {\n provider: 'wasm',\n hasWebGPU: false,\n hasWebNN: false,\n estimatedVRAM: 0,\n adapterLimits: null,\n vramProbe: null,\n recommendedQuantization: 'int8',\n };\n\n // Check WebGPU availability.\n // NOTE: `'gpu' in navigator` is NOT sufficient to conclude WebGPU works.\n // A browser can expose navigator.gpu and still return null from\n // requestAdapter() (no GPU, driver blocklisted, headless). We therefore\n // always request an adapter, and we bound the wait: requestAdapter() is\n // specified to settle, but a hung driver must not stall the whole SDK.\n if (typeof navigator !== 'undefined' && 'gpu' in navigator) {\n try {\n const gpu = (navigator as any).gpu;\n const adapter = await RuntimeManager.withTimeout(\n Promise.resolve(gpu.requestAdapter()),\n ADAPTER_TIMEOUT_MS\n );\n if (adapter) {\n capabilities.hasWebGPU = true;\n capabilities.provider = 'webgpu';\n\n const maxBufferSize = adapter.limits?.maxBufferSize || 0;\n const maxStorageSize = adapter.limits?.maxStorageBufferBindingSize || 0;\n capabilities.adapterLimits = {\n maxBufferSize,\n maxStorageBufferBindingSize: maxStorageSize,\n };\n\n // Probe what the device actually allocates instead of treating the\n // adapter's baseline limits as physical VRAM.\n const probe = await RuntimeManager.probeVRAM(adapter);\n capabilities.vramProbe = probe;\n capabilities.estimatedVRAM = probe.available\n ? probe.maxAllocationBytes\n : Math.max(maxBufferSize, maxStorageSize);\n\n const vramGB = capabilities.estimatedVRAM / (1024 * 1024 * 1024);\n if (vramGB >= 4) {\n capabilities.recommendedQuantization = 'fp16';\n } else if (vramGB >= 1) {\n capabilities.recommendedQuantization = 'int8';\n } else {\n capabilities.recommendedQuantization = 'int4';\n }\n }\n } catch {\n // WebGPU not available or adapter request failed\n }\n }\n\n // Check WebNN availability\n if (typeof navigator !== 'undefined' && 'ml' in navigator) {\n try {\n const ml = (navigator as any).ml;\n if (ml) {\n capabilities.hasWebNN = true;\n if (!capabilities.hasWebGPU) {\n capabilities.provider = 'webnn';\n }\n }\n } catch {\n // WebNN not available\n }\n }\n\n this.cachedCapabilities = capabilities;\n return capabilities;\n }\n\n /**\n * Get the best available execution provider with smart fallback.\n * Priority: WebGPU → WebNN → WASM\n */\n static async getBestExecutionProvider(): Promise<string> {\n const caps = await this.detectCapabilities();\n return caps.provider;\n }\n\n /**\n * Create an ONNX inference session with automatic provider selection.\n * Falls back gracefully if the preferred provider fails.\n *\n * Returns BOTH the session and the provider that actually served it. The\n * detected capability (`detectCapabilities().provider`) is only a preference:\n * a provider can be detected as available and still fail to create a session\n * (for example onnxruntime-web only registers the WebGPU execution provider\n * in some builds/versions). Callers must report the returned `provider`, not\n * the detected one, or `EdgeInfer.executionProvider` will lie.\n */\n static async createSession(\n modelBuffer: ArrayBuffer,\n providers?: string[]\n ): Promise<{ session: ort.InferenceSession; provider: string }> {\n const requestedProviders = providers || [await this.getBestExecutionProvider()];\n\n // Try each provider in order, falling back on failure\n for (const provider of requestedProviders) {\n try {\n const session = await ort.InferenceSession.create(\n modelBuffer,\n {\n executionProviders: [provider],\n graphOptimizationLevel: 'all',\n }\n );\n return { session, provider };\n } catch (err) {\n console.warn(`EdgeInfer: Failed to create session with provider \"${provider}\", trying next...`, err);\n }\n }\n\n // Final fallback: WASM (should always work)\n console.warn('EdgeInfer: All preferred providers failed, falling back to WASM');\n const session = await ort.InferenceSession.create(modelBuffer, {\n executionProviders: ['wasm'],\n graphOptimizationLevel: 'all',\n });\n return { session, provider: 'wasm' };\n }\n\n /**\n * Empirically probe the largest single storage buffer the adapter's device\n * will allocate. Allocates and destroys one buffer at a time; never relies on\n * `maxBufferSize` as if it were physical VRAM.\n */\n static async probeVRAM(\n adapter: any,\n options: VRAMProbeOptions = {}\n ): Promise<VRAMProbeResult> {\n const limits = {\n maxBufferSize: Number(adapter?.limits?.maxBufferSize) || 0,\n maxStorageBufferBindingSize:\n Number(adapter?.limits?.maxStorageBufferBindingSize) || 0,\n };\n const unavailable: VRAMProbeResult = {\n available: false,\n maxAllocationBytes: 0,\n testedAllocations: [],\n failedAllocationBytes: null,\n adapterLimits: limits,\n deviceCreated: false,\n probe: 'unavailable',\n };\n\n if (!adapter || typeof adapter.requestDevice !== 'function') return unavailable;\n\n let device: any;\n try {\n device = await adapter.requestDevice();\n } catch {\n return unavailable;\n }\n if (!device || typeof device.createBuffer !== 'function') {\n return { ...unavailable, deviceCreated: Boolean(device) };\n }\n\n const MIB = 1024 * 1024;\n const start = Math.max(1, options.startBytes ?? 64 * MIB);\n const configuredMax = Math.max(start, options.maxBytes ?? 4 * 1024 * MIB);\n const max = limits.maxBufferSize > 0\n ? Math.min(configuredMax, limits.maxBufferSize)\n : configuredMax;\n const step = Math.max(1, options.stepBytes ?? 32 * MIB);\n const tested: number[] = [];\n const STORAGE = 0x80;\n const COPY_DST = 0x8;\n\n const attempt = (size: number): boolean => {\n tested.push(size);\n try {\n const buffer = device.createBuffer({ size, usage: STORAGE | COPY_DST });\n buffer?.destroy?.();\n return true;\n } catch {\n return false;\n }\n };\n\n let low = 0;\n let high = 0;\n let size = Math.min(start, max);\n while (size >= 1) {\n if (attempt(size)) {\n low = size;\n break;\n }\n high = size;\n if (size === 1) break;\n size = Math.max(1, Math.floor(size / 2));\n }\n\n if (low === 0) {\n device.destroy?.();\n return {\n ...unavailable,\n testedAllocations: tested,\n failedAllocationBytes: high || null,\n deviceCreated: true,\n probe: 'limits',\n };\n }\n\n let next = Math.min(max, low * 2);\n while (next > low && tested.length < 16) {\n if (attempt(next)) {\n low = next;\n next = Math.min(max, low * 2);\n if (low === max) break;\n } else {\n high = next;\n break;\n }\n }\n if (high === 0) high = Math.min(max, low * 2);\n\n while (high - low > step && tested.length < 24) {\n const mid = Math.floor((low + high) / 2);\n if (mid <= low || mid >= high) break;\n if (attempt(mid)) low = mid;\n else high = mid;\n }\n\n device.destroy?.();\n return {\n available: true,\n maxAllocationBytes: low,\n testedAllocations: tested,\n failedAllocationBytes: high > low ? high : null,\n adapterLimits: limits,\n deviceCreated: true,\n probe: 'empirical',\n };\n }\n\n /**\n * Resolve `promise`, or resolve to `null` if it has not settled within `ms`.\n * Used to stop a hung GPU driver from blocking model loading forever.\n */\n private static withTimeout<T>(promise: Promise<T>, ms: number): Promise<T | null> {\n let timer: any;\n return Promise.race([\n promise.then((v) => { clearTimeout(timer); return v; }),\n new Promise<null>((resolve) => {\n timer = setTimeout(() => {\n console.warn(`EdgeInfer: navigator.gpu.requestAdapter() did not settle within ${ms}ms; falling back to WASM.`);\n resolve(null);\n }, ms);\n if (typeof timer?.unref === 'function') timer.unref();\n }),\n ]);\n }\n\n /**\n * Estimate if a model of given size (bytes) can fit in available VRAM.\n */\n static async canFitModel(modelSizeBytes: number): Promise<boolean> {\n const caps = await this.detectCapabilities();\n if (!caps.hasWebGPU) return true; // WASM uses system RAM, not VRAM\n // Model typically needs 1.5x its size in VRAM (weights + activations)\n return caps.estimatedVRAM >= modelSizeBytes * 1.5;\n }\n\n /**\n * Reset cached capabilities (useful for testing or re-detection).\n */\n static resetCache(): void {\n this.cachedCapabilities = null;\n }\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2024-2026 Soumya Debnath\n\nimport { withDownloadDeadline, DownloadOptions } from './download';\n\nexport interface TokenizerConfig {\n vocab: Record<string, number>;\n /** Keep the legacy uncased default; set false for cased WordPiece vocabularies. */\n lowercase?: boolean;\n /**\n * BPE merge rules, either `\"a b\"` (older HuggingFace tokenizer.json) or\n * `[\"a\", \"b\"]` (newer tokenizer.json). Accepted and normalised. When present,\n * `encode()` applies these merges and preserves case by default; otherwise it\n * uses WordPiece.\n */\n merges?: Array<string | [string, string]>;\n specialTokens?: Record<string, number>;\n maxLength?: number;\n padTokenId?: number;\n unkTokenId?: number;\n clsTokenId?: number;\n sepTokenId?: number;\n /**\n * Optional marker prepended to the first BPE piece of each word, e.g. `\"▁\"`\n * for SentencePiece vocabularies or `\"Ġ\"` for byte-level BPE vocabularies.\n * Without it, pieces are looked up exactly as produced by the merge table.\n */\n bpeSpaceMarker?: string;\n}\n\nexport interface EncodingResult {\n inputIds: Int32Array;\n attentionMask: Int32Array;\n tokenTypeIds?: Int32Array;\n /** int64 view for ONNX models declared as `tensor(int64)`. */\n inputIdsInt64: BigInt64Array;\n attentionMaskInt64: BigInt64Array;\n tokenTypeIdsInt64?: BigInt64Array;\n}\n\n/**\n * Production BPE/WordPiece tokenizer for ONNX model inference.\n * Supports loading vocabularies from JSON, encoding text to token IDs,\n * and decoding token IDs back to text.\n */\nexport class Tokenizer {\n private lowercase: boolean;\n private vocab: Map<string, number>;\n private inverseVocab: Map<number, string>;\n private merges: Array<[string, string]>;\n private specialTokens: Map<string, number>;\n private maxLength: number;\n private padTokenId: number;\n private unkTokenId: number;\n private clsTokenId: number;\n private sepTokenId: number;\n private bpeCache: Map<string, string[]>;\n private mergeRanks: Map<string, number>;\n private usesBPE: boolean;\n private bpeSpaceMarker: string;\n\n constructor(config: TokenizerConfig) {\n this.vocab = new Map(Object.entries(config.vocab));\n this.inverseVocab = new Map<number, string>();\n for (const [token, id] of this.vocab) {\n this.inverseVocab.set(id, token);\n }\n\n // `merges` may arrive in either HuggingFace form:\n // older tokenizer.json: [\"a b\", \"lo w\"] (space-separated string)\n // newer tokenizer.json: [[\"a\",\"b\"], [\"lo\",\"w\"]] (pre-split pair)\n // Calling .split() on the array form throws \"m.split is not a function\",\n // so both shapes are handled here.\n this.merges = ((config.merges || []) as Array<string | [string, string]>).map(m => {\n if (Array.isArray(m)) {\n return [m[0], m[1]] as [string, string];\n }\n const parts = String(m).split(' ');\n return [parts[0], parts[1]] as [string, string];\n });\n\n this.specialTokens = new Map(Object.entries(config.specialTokens || {}));\n this.maxLength = config.maxLength || 512;\n this.padTokenId = config.padTokenId ?? 0;\n this.unkTokenId = config.unkTokenId ?? 100;\n this.clsTokenId = config.clsTokenId ?? 101;\n this.sepTokenId = config.sepTokenId ?? 102;\n this.bpeCache = new Map();\n this.usesBPE = this.merges.length > 0;\n this.bpeSpaceMarker = config.bpeSpaceMarker ?? '';\n\n this.mergeRanks = new Map();\n this.merges.forEach(([first, second], rank) => {\n this.mergeRanks.set(`${first} ${second}`, rank);\n });\n\n // Older WordPiece-only callers relied on an implicit uncased default. A\n // merge table means the vocabulary is BPE (typically cased), so preserving\n // case is the only safe default there.\n this.lowercase = config.lowercase ?? !this.usesBPE;\n }\n\n /**\n * Load tokenizer configuration from a JSON URL (tokenizer.json or vocab.json).\n */\n static async fromUrl(url: string, options: DownloadOptions = {}): Promise<Tokenizer> {\n const config = await withDownloadDeadline(async signal => {\n const response = await fetch(url, { signal });\n if (!response.ok) {\n await response.body?.cancel();\n throw new Error(`Failed to load tokenizer from ${url}: ${response.status}`);\n }\n return response.json();\n }, options);\n\n // Handle HuggingFace tokenizer.json format\n if (config.model && config.model.vocab) {\n const specialTokens: Record<string, number> = {};\n if (config.added_tokens) {\n for (const t of config.added_tokens) {\n specialTokens[t.content] = t.id;\n }\n }\n return new Tokenizer({\n vocab: config.model.vocab,\n lowercase: config.normalizer === undefined\n ? undefined\n : Tokenizer.normalizerLowercase(config.normalizer),\n merges: config.model.merges || [],\n specialTokens,\n maxLength: config.truncation?.max_length || 512,\n padTokenId: specialTokens['[PAD]'] ?? 0,\n unkTokenId: specialTokens['[UNK]'] ?? 100,\n clsTokenId: specialTokens['[CLS]'] ?? 101,\n sepTokenId: specialTokens['[SEP]'] ?? 102,\n });\n }\n\n // Handle simple vocab.json format (key -> id mapping)\n return new Tokenizer({ vocab: config });\n }\n\n private static normalizerLowercase(normalizer: unknown): boolean {\n if (normalizer === undefined) return true; // Legacy default for omitted config.\n if (normalizer === null) return false; // Explicit identity normalizer.\n if (typeof normalizer !== 'object') throw new Error('Unsupported tokenizer normalizer');\n const value = normalizer as Record<string, unknown>;\n if (value.type === 'Lowercase') return true;\n // Other normalization (accent stripping, CJK spacing, Unicode normalization)\n // is not implemented. Reject it instead of silently changing token IDs.\n if (value.type === 'BertNormalizer' && typeof value.lowercase === 'boolean'\n && value.strip_accents === false && value.clean_text === false && value.handle_chinese_chars === false) {\n return value.lowercase;\n }\n throw new Error('Unsupported tokenizer normalizer; only identity, Lowercase, or casing-only BertNormalizer is supported');\n }\n\n /**\n * Encode text into token IDs with attention mask.\n * Handles WordPiece tokenization for BERT-like models.\n */\n encode(text: string, options?: { addSpecialTokens?: boolean; maxLength?: number; padding?: boolean }): EncodingResult {\n const addSpecial = options?.addSpecialTokens !== false;\n const maxLen = options?.maxLength || this.maxLength;\n const padding = options?.padding ?? false;\n\n // Pre-tokenize: lowercase, split on whitespace and punctuation\n const words = this.preTokenize(text);\n \n // WordPiece / BPE tokenization\n const tokenIds: number[] = [];\n \n if (addSpecial) {\n tokenIds.push(this.clsTokenId);\n }\n\n for (const word of words) {\n const subTokens = this.tokenizeWord(word);\n for (const subToken of subTokens) {\n if (tokenIds.length >= maxLen - (addSpecial ? 1 : 0)) break;\n tokenIds.push(subToken);\n }\n }\n\n if (addSpecial) {\n tokenIds.push(this.sepTokenId);\n }\n\n // Truncate to maxLength\n const truncated = tokenIds.slice(0, maxLen);\n \n // Guard against empty encoding producing empty tensors (crashes ONNX)\n if (truncated.length === 0) {\n const fallback = new Int32Array([this.padTokenId]);\n return {\n inputIds: fallback,\n attentionMask: new Int32Array([0]),\n inputIdsInt64: Tokenizer.toInt64(fallback),\n attentionMaskInt64: new BigInt64Array([0n]),\n };\n }\n\n // Build attention mask\n const attentionMask = new Int32Array(padding ? maxLen : truncated.length);\n attentionMask.fill(1, 0, truncated.length);\n\n // Pad if requested\n const inputIds = new Int32Array(padding ? maxLen : truncated.length);\n inputIds.set(truncated);\n if (padding) {\n inputIds.fill(this.padTokenId, truncated.length);\n }\n\n return {\n inputIds,\n attentionMask,\n inputIdsInt64: Tokenizer.toInt64(inputIds),\n attentionMaskInt64: Tokenizer.toInt64(attentionMask),\n };\n }\n\n /**\n * Decode token IDs back to text.\n */\n decode(tokens: Int32Array | number[]): string {\n const tokenArray = tokens instanceof Int32Array ? Array.from(tokens) : tokens;\n const words: string[] = [];\n\n for (const id of tokenArray) {\n if (id === this.padTokenId || id === this.clsTokenId || id === this.sepTokenId) continue;\n const token = this.inverseVocab.get(id);\n if (!token) {\n words.push('[UNK]');\n } else if (token.startsWith('##')) {\n // WordPiece continuation token\n if (words.length > 0) {\n words[words.length - 1] += token.slice(2);\n } else {\n words.push(token.slice(2));\n }\n } else if (token.startsWith('\\u2581') || token.startsWith('\\u0120')) {\n // SentencePiece (`▁`) and byte-level BPE (`Ġ`) word markers.\n words.push(token.slice(1));\n } else {\n words.push(token);\n }\n }\n\n return words.join(' ');\n }\n\n /**\n * Get vocabulary size.\n */\n get vocabSize(): number {\n return this.vocab.size;\n }\n\n /**\n * Resolve a special token (e.g. `</s>`, `<|endoftext|>`) to its ID, whether it\n * was declared in `specialTokens` or is present in the main vocabulary.\n */\n getSpecialTokenId(token: string): number | undefined {\n return this.specialTokens.get(token) ?? this.vocab.get(token);\n }\n\n /**\n * Pre-tokenize text: lowercase, split on whitespace and punctuation boundaries.\n */\n private preTokenize(text: string): string[] {\n const normalized = (this.lowercase ? text.toLowerCase() : text).trim();\n if (!normalized) return [];\n \n // Split on whitespace and keep punctuation as separate tokens\n // Uses Unicode-aware patterns to handle emojis, CJK, Arabic, accented chars\n const tokens: string[] = [];\n let current = '';\n\n for (const char of normalized) {\n if (/\\s/.test(char)) {\n if (current) tokens.push(current);\n current = '';\n } else if (/[.,!?;:'\"()\\[\\]{}\\-\\/\\\\@#$%^&*~`|<>]/.test(char) || /\\p{P}/u.test(char)) {\n if (current) tokens.push(current);\n tokens.push(char);\n current = '';\n } else {\n current += char;\n }\n }\n if (current) tokens.push(current);\n return tokens;\n }\n\n /**\n * Tokenize a single word using the tokenizer's model type: BPE when a merge\n * table is present, WordPiece otherwise.\n */\n private tokenizeWord(word: string): number[] {\n if (this.usesBPE) return this.tokenizeWordBPE(word);\n\n // Check if whole word is in vocabulary\n if (this.vocab.has(word)) {\n return [this.vocab.get(word)!];\n }\n\n // WordPiece: greedily match longest subword from left to right\n const tokens: number[] = [];\n let start = 0;\n\n while (start < word.length) {\n let end = word.length;\n let found = false;\n\n while (start < end) {\n let substr = word.slice(start, end);\n if (start > 0) {\n substr = '##' + substr;\n }\n\n if (this.vocab.has(substr)) {\n tokens.push(this.vocab.get(substr)!);\n found = true;\n break;\n }\n end--;\n }\n\n if (!found) {\n // Character not in vocab, use [UNK]\n tokens.push(this.unkTokenId);\n start++;\n } else {\n start = end;\n }\n }\n\n return tokens;\n }\n\n /**\n * Apply the merge table to a word, then map the resulting pieces to IDs.\n * Unknown pieces fall back to the unknown token rather than throwing, which\n * matches ONNX Runtime's text-tokenizer behaviour.\n */\n private tokenizeWordBPE(word: string): number[] {\n const whole = this.vocab.get(\n this.bpeSpaceMarker ? this.bpeSpaceMarker + word : word\n );\n if (whole !== undefined) return [whole];\n\n const pieces = this.applyBPE(word);\n const ids: number[] = [];\n\n for (let i = 0; i < pieces.length; i++) {\n const piece = i === 0 && this.bpeSpaceMarker\n ? this.bpeSpaceMarker + pieces[i]\n : pieces[i];\n const id = this.vocab.get(piece);\n if (id !== undefined) {\n ids.push(id);\n continue;\n }\n ids.push(this.unkTokenId);\n }\n\n return ids;\n }\n\n /**\n * Apply BPE merges to a word (for BPE-style tokenizers like GPT-2/Llama).\n * Merge rules are applied in ascending rank order until no adjacent pair is\n * present in the merge table; caching is keyed on the original word.\n */\n private applyBPE(word: string): string[] {\n const cached = this.bpeCache.get(word);\n if (cached) return cached;\n\n let tokens = word.split('');\n if (tokens.length <= 1 || this.mergeRanks.size === 0) {\n this.bpeCache.set(word, tokens);\n return tokens;\n }\n\n while (tokens.length > 1) {\n let bestRank = Number.POSITIVE_INFINITY;\n for (let i = 0; i < tokens.length - 1; i++) {\n const rank = this.mergeRanks.get(`${tokens[i]} ${tokens[i + 1]}`);\n if (rank !== undefined && rank < bestRank) bestRank = rank;\n }\n if (bestRank === Number.POSITIVE_INFINITY) break;\n\n const merged: string[] = [];\n for (let i = 0; i < tokens.length; i++) {\n if (\n i < tokens.length - 1 &&\n this.mergeRanks.get(`${tokens[i]} ${tokens[i + 1]}`) === bestRank\n ) {\n merged.push(tokens[i] + tokens[i + 1]);\n i++;\n } else {\n merged.push(tokens[i]);\n }\n }\n\n if (merged.length === tokens.length) break;\n tokens = merged;\n }\n\n this.bpeCache.set(word, tokens);\n return tokens;\n }\n\n private static toInt64(values: Int32Array): BigInt64Array {\n const out = new BigInt64Array(values.length);\n for (let i = 0; i < values.length; i++) out[i] = BigInt(values[i]);\n return out;\n }\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2024-2026 Soumya Debnath\n\nexport class ImageProcessor {\n static imageDataToFloat32Array(\n imageData: ImageData,\n options: { normalize?: boolean; layout?: 'NCHW' | 'NHWC' } = {}\n ): Float32Array {\n const { normalize = true, layout = 'NCHW' } = options;\n const { width, height, data } = imageData;\n const size = width * height;\n const float32Data = new Float32Array(size * 3);\n\n for (let i = 0; i < size; i++) {\n const r = data[i * 4];\n const g = data[i * 4 + 1];\n const b = data[i * 4 + 2];\n\n const nr = normalize ? r / 255 : r;\n const ng = normalize ? g / 255 : g;\n const nb = normalize ? b / 255 : b;\n\n if (layout === 'NCHW') {\n float32Data[i] = nr;\n float32Data[size + i] = ng;\n float32Data[2 * size + i] = nb;\n } else {\n float32Data[i * 3] = nr;\n float32Data[i * 3 + 1] = ng;\n float32Data[i * 3 + 2] = nb;\n }\n }\n return float32Data;\n }\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2024-2026 Soumya Debnath\n\nimport * as ort from 'onnxruntime-web';\nimport { ModelCache } from './model-cache';\nimport { DownloadOptions, checkDownloadAbort } from './download';\nimport { RuntimeManager, GPUCapabilities } from './runtime-manager';\nimport { ModelOptions, ClassificationResult, Detection } from './types';\nimport { Tokenizer, TokenizerConfig, EncodingResult } from './tokenizer';\nimport { ImageProcessor } from './image-processor';\n\nfunction throwIfAborted(signal?: AbortSignal): void {\n if (signal?.aborted) {\n throw signal.reason ?? new DOMException('Generation aborted', 'AbortError');\n }\n}\n\nfunction normalizeChatMessages(messages: ChatMessage[]): ChatMessage[] {\n if (!Array.isArray(messages) || messages.length === 0) {\n throw new Error('chat requires at least one message');\n }\n return messages.map((message, index) => {\n if (!message || typeof message !== 'object') {\n throw new Error(`chat message ${index} must be an object`);\n }\n if (message.role !== 'system' && message.role !== 'user' && message.role !== 'assistant') {\n throw new Error(`chat message ${index} has an invalid role`);\n }\n if (typeof message.content !== 'string') {\n throw new Error(`chat message ${index} content must be a string`);\n }\n return { role: message.role, content: message.content };\n });\n}\n\nfunction defaultChatTemplate(messages: ChatMessage[]): string {\n return `${messages.map((message) => `<|${message.role}|>${message.content}`).join('\\n')}\\n<|assistant|>`;\n}\n\nexport interface EdgeInferOptions extends ModelOptions, DownloadOptions {\n tokenizerUrl?: string;\n tokenizerConfig?: TokenizerConfig;\n /**\n * Force int64 `input_ids`/`attention_mask` tensors. By default the engine\n * inspects ONNX input metadata and falls back to int32.\n */\n int64Inputs?: boolean;\n}\n\nexport interface GenerateOptions {\n /** Maximum number of new tokens to emit. Default: 64. */\n maxNewTokens?: number;\n /** 0 (default) is greedy decoding; >0 enables temperature sampling. */\n temperature?: number;\n /** Optional top-k truncation for sampling. 0 disables it. */\n topK?: number;\n /** Stop token. Defaults to the tokenizer's `</s>` when present. */\n eosTokenId?: number;\n /** Abort an in-flight stream between decode steps. */\n signal?: AbortSignal;\n}\n\nexport interface GenerationResult {\n text: string;\n tokenIds: number[];\n}\n\nexport interface GenerationEvent {\n tokenId: number;\n /** Best-effort decoded delta for this token. */\n text: string;\n index: number;\n}\n\nexport interface ChatMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\nexport interface ChatOptions extends GenerateOptions {\n /** Override the default role-marker template for the target model. */\n chatTemplate?: (messages: ChatMessage[]) => string;\n}\n\nexport interface ChatResult extends GenerationResult {\n prompt: string;\n}\n\n/**\n * EdgeInfer — On-Device WebGPU/WASM AI Inference Engine.\n * \n * Executes ONNX models directly inside the browser using WebGPU (preferred)\n * or WebAssembly SIMD (fallback), with zero server API costs.\n * \n * Powered by: BitNet b1.58, Mamba-2 SSM, Matryoshka MRL research.\n */\nexport class EdgeInfer {\n private session: ort.InferenceSession;\n private tokenizer: Tokenizer | null = null;\n private _inputNames: readonly string[];\n private _outputNames: readonly string[];\n private _modelSize: number;\n private _provider: string = 'wasm';\n private _int64Inputs: boolean;\n\n private constructor(\n session: ort.InferenceSession,\n modelSize: number,\n provider: string,\n int64Inputs: boolean,\n tokenizer?: Tokenizer\n ) {\n this.session = session;\n this._inputNames = session.inputNames;\n this._outputNames = session.outputNames;\n this._modelSize = modelSize;\n this._provider = provider;\n this._int64Inputs = int64Inputs;\n this.tokenizer = tokenizer || null;\n }\n\n /**\n * Load a model from URL with automatic caching and optimal provider selection.\n */\n static async load(modelUrl: string, options?: EdgeInferOptions): Promise<EdgeInfer> {\n const cache = new ModelCache(options?.cacheName);\n const buffer = await cache.getModel(modelUrl, options?.forceDownload, options);\n return EdgeInfer.fromBuffer(buffer, options);\n }\n\n /**\n * Create an EdgeInfer instance from a pre-loaded model buffer.\n */\n static async fromBuffer(buffer: ArrayBuffer, options?: EdgeInferOptions): Promise<EdgeInfer> {\n // `provider` is the provider that actually created the session, which is\n // not necessarily the detected preference — see RuntimeManager.createSession.\n checkDownloadAbort(options?.signal);\n const { session, provider } = await RuntimeManager.createSession(\n buffer,\n options?.executionProviders\n );\n\n try {\n checkDownloadAbort(options?.signal);\n // Load tokenizer if URL provided\n let tokenizer: Tokenizer | undefined;\n if (options?.tokenizerUrl) {\n tokenizer = await Tokenizer.fromUrl(options.tokenizerUrl, options);\n } else if (options?.tokenizerConfig) {\n tokenizer = new Tokenizer(options.tokenizerConfig);\n }\n\n checkDownloadAbort(options?.signal);\n return new EdgeInfer(session, buffer.byteLength, provider, options?.int64Inputs ?? false, tokenizer);\n } catch (error) {\n try { await session.release(); } catch { /* Preserve the original load failure. */ }\n throw error;\n }\n }\n\n /**\n * Set or replace the tokenizer after model load.\n */\n setTokenizer(tokenizer: Tokenizer): void {\n this.tokenizer = tokenizer;\n }\n\n /**\n * Low-level tensor inference.\n * Pass raw tensor inputs and get raw tensor outputs.\n *\n * `shapes` optionally gives the ONNX tensor shape per input name. When an\n * input has no explicit shape it defaults to `[1, data.length]`, which is\n * correct for 2-D sequence inputs (`input_ids`, `attention_mask`) but wrong\n * for anything of higher rank — a vision model declaring\n * `pixel_values: [1,3,224,224]` is rank 4 and rejects a rank-2 tensor with\n * \"Invalid rank for input\". Pass `shapes` for such models.\n */\n async predict(\n inputs: Record<string, Float32Array | Int32Array | BigInt64Array>,\n shapes?: Record<string, readonly number[]>\n ): Promise<Record<string, Float32Array>> {\n const results = await this.runInference(inputs, shapes);\n const outputMap: Record<string, Float32Array> = {};\n\n for (const [key, tensor] of Object.entries(results)) {\n outputMap[key] = tensor.data as Float32Array;\n }\n\n return outputMap;\n }\n\n /**\n * Classify text using the loaded model.\n * Requires a tokenizer to be configured.\n */\n async classify(text: string): Promise<ClassificationResult[]> {\n this.requireTokenizer();\n \n const encoding = this.tokenizer!.encode(text, { addSpecialTokens: true });\n const inputs = this.textInputs(encoding);\n\n const result = await this.predict(inputs);\n const output = result[this._outputNames[0]];\n \n if (!output) return [];\n\n // Apply softmax to get probabilities\n const probs = this.softmax(output);\n \n return Array.from(probs).map((score, idx) => ({\n label: `Class_${idx}`,\n score\n })).sort((a, b) => b.score - a.score);\n }\n\n /**\n * Generate text embeddings for semantic search / RAG.\n * Returns a Float32Array of embedding dimensions.\n */\n async embed(text: string): Promise<Float32Array> {\n this.requireTokenizer();\n\n const encoding = this.tokenizer!.encode(text, { addSpecialTokens: true });\n const inputs = this.textInputs(encoding);\n\n const result = await this.runInference(inputs);\n const output = result[this._outputNames[0]];\n \n if (!output) return new Float32Array();\n\n if (output.type !== 'float32') {\n throw new Error('EdgeInfer: Embedding output must be a float32 tensor.');\n }\n\n return this.poolEmbedding(output.data as Float32Array, output.dims, encoding.attentionMask);\n }\n\n /**\n * Generate Matryoshka-truncated embeddings at specified dimension.\n * Supports variable-dimension MRL embeddings (64d → 256d → 768d).\n */\n async embedMatryoshka(text: string, dimension: number): Promise<Float32Array> {\n const fullEmbedding = await this.embed(text);\n if (dimension >= fullEmbedding.length) return fullEmbedding;\n\n // Truncate to requested dimension (MRL front-loads important info)\n const truncated = fullEmbedding.slice(0, dimension);\n\n // L2 normalize after truncation\n return this.l2Normalize(truncated);\n }\n\n /**\n * Greedy or temperature-sampled autoregressive generation.\n *\n * Decoder models that expose `present.*` outputs and `past_key_values.*`\n * inputs reuse those tensors across steps (KV-cache). Models without cache\n * inputs are re-run over the full sequence each step.\n */\n async generate(prompt: string, options: GenerateOptions = {}): Promise<GenerationResult> {\n this.requireTokenizer();\n const tokenIds: number[] = [];\n for await (const event of this.generateStream(prompt, options)) {\n tokenIds.push(event.tokenId);\n }\n return {\n text: this.tokenizer!.decode(tokenIds),\n tokenIds,\n };\n }\n\n /**\n * Stream generated tokens. The decoder loop is identical to generate(), but\n * each token is yielded as soon as it is chosen so a UI can paint before the\n * full completion finishes.\n */\n async *generateStream(\n prompt: string,\n options: GenerateOptions = {}\n ): AsyncGenerator<GenerationEvent, void, unknown> {\n this.requireTokenizer();\n\n const maxNewTokens = Math.max(0, options.maxNewTokens ?? 64);\n const temperature = options.temperature ?? 0;\n const topK = options.topK ?? 0;\n const tokenizer = this.tokenizer!;\n const eosTokenId = options.eosTokenId\n ?? tokenizer.getSpecialTokenId('</s>')\n ?? tokenizer.getSpecialTokenId('<|endoftext|>');\n\n const encoding = tokenizer.encode(prompt, { addSpecialTokens: true });\n const promptIds = Array.from(encoding.inputIds);\n const int64 = this.useInt64Inputs();\n\n const makeIds = (values: number[]): Int32Array | BigInt64Array =>\n int64\n ? BigInt64Array.from(values, v => BigInt(v))\n : Int32Array.from(values);\n\n const dtype = int64 ? 'int64' : 'int32';\n let current = promptIds;\n let past: Record<string, ort.Tensor> = {};\n const generated: number[] = [];\n\n for (let step = 0; step < maxNewTokens; step++) {\n throwIfAborted(options.signal);\n const totalLength = promptIds.length + generated.length;\n const inputs: Record<string, ort.Tensor> = {\n input_ids: new ort.Tensor(dtype, makeIds(current), [1, current.length]),\n attention_mask: new ort.Tensor(dtype, makeIds(new Array(totalLength).fill(1)), [1, totalLength]),\n };\n\n if (this._inputNames.includes('position_ids')) {\n const offset = totalLength - current.length;\n inputs.position_ids = new ort.Tensor(\n dtype,\n makeIds(current.map((_, i) => offset + i)),\n [1, current.length]\n );\n }\n\n for (const [name, tensor] of Object.entries(past)) {\n if (this._inputNames.includes(name)) inputs[name] = tensor;\n }\n\n const results = await this.session.run(inputs);\n const logits = this.findLogits(results);\n const next = this.pickNextToken(logits, temperature, topK);\n generated.push(next);\n yield {\n tokenId: next,\n text: tokenizer.decode([next]),\n index: generated.length - 1,\n };\n\n if (eosTokenId !== undefined && next === eosTokenId) break;\n\n const nextPast: Record<string, ort.Tensor> = {};\n for (const outputName of this._outputNames) {\n const inputName = EdgeInfer.pastInputName(outputName);\n if (inputName && this._inputNames.includes(inputName) && results[outputName]) {\n nextPast[inputName] = results[outputName];\n }\n }\n\n if (Object.keys(nextPast).length > 0) {\n past = nextPast;\n current = [next];\n } else {\n past = {};\n current = [...promptIds, ...generated];\n }\n }\n }\n\n /**\n * Stream a chat completion using a role-marker template. The default template\n * is model-agnostic; pass `chatTemplate` to match the target tokenizer.\n */\n async *chatStream(\n messages: ChatMessage[],\n options: ChatOptions = {}\n ): AsyncGenerator<GenerationEvent, void, unknown> {\n this.requireTokenizer();\n const normalized = normalizeChatMessages(messages);\n const prompt = (options.chatTemplate ?? defaultChatTemplate)(normalized);\n yield* this.generateStream(prompt, options);\n }\n\n /** Collect a chat completion. */\n async chat(messages: ChatMessage[], options: ChatOptions = {}): Promise<ChatResult> {\n this.requireTokenizer();\n const normalized = normalizeChatMessages(messages);\n const prompt = (options.chatTemplate ?? defaultChatTemplate)(normalized);\n const tokenIds: number[] = [];\n for await (const event of this.generateStream(prompt, options)) {\n tokenIds.push(event.tokenId);\n }\n return {\n text: this.tokenizer!.decode(tokenIds),\n tokenIds,\n prompt,\n };\n }\n\n /** Pick the last-token logits from the first output that looks like logits. */\n private findLogits(results: ort.InferenceSession.ReturnType): ort.Tensor {\n const exact = results['logits'];\n if (exact) return exact;\n for (const name of Object.keys(results)) {\n if (name.toLowerCase().includes('logits')) return results[name];\n }\n return results[this._outputNames[0]];\n }\n\n /** Argmax (temperature 0) or temperature/top-k sampling over last-token logits. */\n private pickNextToken(logits: ort.Tensor, temperature: number, topK: number): number {\n const dims = logits.dims;\n const vocabSize = dims[dims.length - 1];\n const seqLen = dims.length >= 3 ? dims[dims.length - 2] : 1;\n const data = logits.data as Float32Array;\n const offset = Math.max(0, (seqLen - 1) * vocabSize);\n\n if (temperature <= 0) {\n let best = 0;\n let bestValue = -Infinity;\n for (let i = 0; i < vocabSize; i++) {\n const value = data[offset + i];\n if (value > bestValue) {\n bestValue = value;\n best = i;\n }\n }\n return best;\n }\n\n const scaled = new Float32Array(vocabSize);\n let maxLogit = -Infinity;\n for (let i = 0; i < vocabSize; i++) {\n scaled[i] = data[offset + i] / temperature;\n if (scaled[i] > maxLogit) maxLogit = scaled[i];\n }\n\n const candidates: Array<{ id: number; prob: number }> = [];\n let sum = 0;\n for (let i = 0; i < vocabSize; i++) {\n const prob = Math.exp(scaled[i] - maxLogit);\n candidates.push({ id: i, prob });\n sum += prob;\n }\n\n if (topK > 0 && topK < candidates.length) {\n candidates.sort((a, b) => b.prob - a.prob);\n candidates.length = topK;\n sum = candidates.reduce((acc, c) => acc + c.prob, 0);\n }\n\n let sample = Math.random() * sum;\n for (const candidate of candidates) {\n sample -= candidate.prob;\n if (sample <= 0) return candidate.id;\n }\n return candidates[candidates.length - 1].id;\n }\n\n private static pastInputName(outputName: string): string | null {\n if (!outputName.startsWith('present')) return null;\n return outputName.replace(/^present/, 'past_key_values');\n }\n\n private useInt64Inputs(): boolean {\n if (this._int64Inputs) return true;\n const metadata = (this.session as unknown as {\n inputMetadata?: Record<string, { type?: string }>;\n }).inputMetadata;\n return metadata?.['input_ids']?.type === 'int64';\n }\n\n /** Build input_ids/attention_mask tensors in the dtype the model declares. */\n private textInputs(encoding: EncodingResult): Record<string, Int32Array | BigInt64Array> {\n const int64 = this.useInt64Inputs();\n const inputs: Record<string, Int32Array | BigInt64Array> = {\n input_ids: int64 ? encoding.inputIdsInt64 : encoding.inputIds,\n attention_mask: int64 ? encoding.attentionMaskInt64 : encoding.attentionMask,\n };\n\n if (this._inputNames.includes('token_type_ids')) {\n inputs['token_type_ids'] = int64\n ? new BigInt64Array(encoding.inputIds.length)\n : new Int32Array(encoding.inputIds.length);\n }\n\n return inputs;\n }\n\n /**\n * Sentiment analysis.\n */\n async sentiment(text: string): Promise<{ label: string; score: number }> {\n const results = await this.classify(text);\n if (results.length === 0) return { label: 'unknown', score: 0 };\n\n const best = results[0]; // Already sorted by score\n const labelMap: Record<string, string> = {\n 'Class_0': 'negative',\n 'Class_1': 'positive',\n 'Class_2': 'neutral',\n };\n\n return {\n label: labelMap[best.label] || best.label,\n score: best.score\n };\n }\n\n /**\n * Classify an image using a vision model.\n */\n async classifyImage(imageData: ImageData, layout?: 'NCHW' | 'NHWC'): Promise<ClassificationResult[]> {\n const effectiveLayout = layout ?? 'NCHW';\n const tensorData = ImageProcessor.imageDataToFloat32Array(imageData, { layout: effectiveLayout });\n\n // Find the image input name\n const inputName = this._inputNames.find(n =>\n n === 'input' || n === 'pixel_values' || n === 'image'\n ) || this._inputNames[0];\n\n const result = await this.predict(\n { [inputName]: tensorData },\n { [inputName]: EdgeInfer.imageShape(imageData, effectiveLayout) }\n );\n const output = result[this._outputNames[0]];\n\n if (!output) return [];\n\n const probs = this.softmax(output);\n \n return Array.from(probs).map((score, idx) => ({\n label: `Class_${idx}`,\n score\n })).sort((a, b) => b.score - a.score).slice(0, 10);\n }\n\n /**\n * Detect objects in an image.\n */\n async detectObjects(imageData: ImageData): Promise<Detection[]> {\n const tensorData = ImageProcessor.imageDataToFloat32Array(imageData);\n\n const inputName = this._inputNames.find(n =>\n n === 'input' || n === 'pixel_values' || n === 'image'\n ) || this._inputNames[0];\n\n const result = await this.predict(\n { [inputName]: tensorData },\n { [inputName]: EdgeInfer.imageShape(imageData, 'NCHW') }\n );\n const output = result[this._outputNames[0]];\n const detections: Detection[] = [];\n \n if (output) {\n // Standard format: [x, y, w, h, score, class_id] per detection\n for (let i = 0; i < output.length; i += 6) {\n const confidence = output[i + 4];\n if (confidence > 0.5) {\n detections.push({\n bbox: [output[i], output[i+1], output[i+2], output[i+3]],\n score: confidence,\n label: `Object_${Math.round(output[i+5])}`\n });\n }\n }\n }\n return detections.sort((a, b) => b.score - a.score);\n }\n\n /**\n * Check GPU capabilities and recommended configuration.\n */\n static async getCapabilities(): Promise<GPUCapabilities> {\n return RuntimeManager.detectCapabilities();\n }\n\n /**\n * Check if WebGPU is available for accelerated inference.\n */\n static async isWebGPUAvailable(): Promise<boolean> {\n const caps = await RuntimeManager.detectCapabilities();\n return caps.hasWebGPU;\n }\n\n get inputNames(): readonly string[] { return this._inputNames; }\n get outputNames(): readonly string[] { return this._outputNames; }\n get modelSize(): number { return this._modelSize; }\n get executionProvider(): string { return this._provider; }\n\n /**\n * Release all resources (ONNX session, GPU memory).\n */\n dispose(): void {\n if (this.session) {\n this.session.release();\n }\n this.tokenizer = null;\n RuntimeManager.resetCache();\n }\n\n // --- Private Helpers ---\n\n /** Run without discarding the output tensor dimensions needed by embed(). */\n private async runInference(\n inputs: Record<string, Float32Array | Int32Array | BigInt64Array>,\n shapes?: Record<string, readonly number[]>\n ): Promise<ort.InferenceSession.ReturnType> {\n const tensorInputs: Record<string, ort.Tensor> = {};\n\n for (const [key, data] of Object.entries(inputs)) {\n let type: 'float32' | 'int32' | 'int64';\n if (data instanceof Float32Array) {\n type = 'float32';\n } else if (data instanceof BigInt64Array) {\n type = 'int64';\n } else {\n type = 'int32';\n }\n const shape = shapes?.[key] ?? [1, data.length];\n tensorInputs[key] = new ort.Tensor(type, data, shape as number[]);\n }\n\n return this.session.run(tensorInputs);\n }\n\n /** ONNX tensor shape for a 3-channel image tensor in the given layout. */\n private static imageShape(\n imageData: { width: number; height: number },\n layout: 'NCHW' | 'NHWC'\n ): number[] {\n const { width, height } = imageData;\n return layout === 'NCHW' ? [1, 3, height, width] : [1, height, width, 3];\n }\n\n private requireTokenizer(): void {\n if (!this.tokenizer) {\n throw new Error(\n 'EdgeInfer: No tokenizer configured. Either pass tokenizerUrl/tokenizerConfig in options, ' +\n 'or call setTokenizer() before using text-based inference methods.'\n );\n }\n }\n\n private softmax(logits: Float32Array): Float32Array {\n let maxLogit = -Infinity;\n for (let i = 0; i < logits.length; i++) {\n if (logits[i] > maxLogit) maxLogit = logits[i];\n }\n const exps = new Float32Array(logits.length);\n let sumExp = 0;\n for (let i = 0; i < logits.length; i++) {\n exps[i] = Math.exp(logits[i] - maxLogit);\n sumExp += exps[i];\n }\n for (let i = 0; i < exps.length; i++) {\n exps[i] /= sumExp;\n }\n return exps;\n }\n\n private poolEmbedding(\n embeddings: Float32Array,\n dims: readonly number[],\n attentionMask: Int32Array\n ): Float32Array {\n // The shape, not divisibility by input length, distinguishes pooled output\n // from per-token output. Both pooled forms retain every model dimension.\n if ((dims.length === 1 || (dims.length === 2 && dims[0] === 1)) &&\n dims[dims.length - 1] > 0) {\n return this.l2Normalize(embeddings);\n }\n\n if (dims.length !== 3 || dims[0] !== 1 || dims[1] < 1 || dims[2] < 1) {\n throw new Error(\n `EdgeInfer: Unsupported embedding output shape [${dims.join(', ')}]. ` +\n 'Expected [hidden], [1, hidden], or [1, sequence, hidden].'\n );\n }\n\n const [, seqLen, hiddenDim] = dims;\n if (seqLen !== attentionMask.length) {\n throw new Error(\n `EdgeInfer: Embedding sequence length ${seqLen} does not match ` +\n `attention mask length ${attentionMask.length}.`\n );\n }\n\n const pooled = new Float32Array(hiddenDim);\n let maskSum = 0;\n\n for (let t = 0; t < seqLen; t++) {\n if (attentionMask[t] === 0) continue;\n maskSum++;\n for (let d = 0; d < hiddenDim; d++) {\n pooled[d] += embeddings[t * hiddenDim + d];\n }\n }\n\n if (maskSum > 0) {\n for (let d = 0; d < hiddenDim; d++) {\n pooled[d] /= maskSum;\n }\n }\n\n return this.l2Normalize(pooled);\n }\n\n private l2Normalize(vec: Float32Array): Float32Array {\n let norm = 0;\n for (let i = 0; i < vec.length; i++) {\n norm += vec[i] * vec[i];\n }\n norm = Math.sqrt(norm);\n if (norm === 0) return vec;\n\n const result = new Float32Array(vec.length);\n for (let i = 0; i < vec.length; i++) {\n result[i] = vec[i] / norm;\n }\n return result;\n }\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2024-2026 Soumya Debnath\n//\n// Browser-local two-stage Matryoshka retrieval.\n// Stage 1: INT8 truncated vectors (default 64 dims) over the full index.\n// Stage 2: FP32 re-ranking of the top candidates at the full dimension.\n\nexport interface VectorRecord {\n id: string;\n text?: string;\n embedding: Float32Array;\n metadata?: Record<string, unknown>;\n}\n\nexport interface SearchResult {\n id: string;\n text?: string;\n metadata?: Record<string, unknown>;\n score: number;\n coarseScore: number;\n}\n\nexport interface VectorStore {\n add(records: VectorRecord[]): Promise<void>;\n getAll(): Promise<VectorRecord[]>;\n clear(): Promise<void>;\n count(): Promise<number>;\n close?(): void;\n}\n\nexport interface MatryoshkaOptions {\n dimensions?: number;\n coarseDimension?: number;\n refineTopK?: number;\n store?: VectorStore;\n}\n\nexport interface SearchOptions {\n topK?: number;\n refineTopK?: number;\n coarseDimension?: number;\n refine?: boolean;\n}\n\nexport function l2Normalize(vector: Float32Array, dimension = vector.length): Float32Array {\n const output = new Float32Array(dimension);\n if (dimension > vector.length) {\n throw new Error(`Cannot normalize ${dimension} dims from a ${vector.length}-dim vector`);\n }\n let norm = 0;\n for (let i = 0; i < dimension; i++) norm += vector[i] * vector[i];\n norm = Math.sqrt(norm);\n if (norm === 0) return output;\n for (let i = 0; i < dimension; i++) output[i] = vector[i] / norm;\n return output;\n}\n\nexport function truncateAndNormalize(vector: Float32Array, dimension: number): Float32Array {\n if (!Number.isInteger(dimension) || dimension < 1) {\n throw new Error(\"dimension must be a positive integer\");\n }\n return l2Normalize(vector, dimension);\n}\n\nexport function quantizeInt8(\n vector: Float32Array,\n dimension = vector.length\n): { data: Int8Array; scale: number } {\n let maxAbs = 0;\n for (let i = 0; i < dimension; i++) {\n const value = Math.abs(vector[i]);\n if (value > maxAbs) maxAbs = value;\n }\n const scale = maxAbs > 0 ? maxAbs / 127 : 1;\n const data = new Int8Array(dimension);\n for (let i = 0; i < dimension; i++) {\n const value = Math.round(vector[i] / scale);\n data[i] = value > 127 ? 127 : value < -127 ? -127 : value;\n }\n return { data, scale };\n}\n\nexport function dequantizeInt8(data: Int8Array, scale: number): Float32Array {\n const output = new Float32Array(data.length);\n for (let i = 0; i < data.length; i++) output[i] = data[i] * scale;\n return output;\n}\n\nfunction dot(a: Float32Array | Int8Array, b: Float32Array | Int8Array, dimension: number): number {\n let sum = 0;\n for (let i = 0; i < dimension; i++) sum += a[i] * b[i];\n return sum;\n}\n\nclass TopKHeap {\n private items: Array<{ index: number; score: number }> = [];\n\n constructor(private readonly k: number) {\n if (k < 1) throw new Error(\"top-k must be positive\");\n }\n\n push(index: number, score: number): void {\n if (this.items.length < this.k) {\n this.items.push({ index, score });\n if (this.items.length === this.k) this.heapify();\n return;\n }\n if (score > this.items[0].score) {\n this.items[0] = { index, score };\n this.siftDown(0);\n }\n }\n\n private heapify(): void {\n for (let i = Math.floor(this.items.length / 2) - 1; i >= 0; i--) this.siftDown(i);\n }\n\n private siftDown(start: number): void {\n let index = start;\n const length = this.items.length;\n for (;;) {\n const left = index * 2 + 1;\n const right = left + 1;\n let smallest = index;\n if (left < length && this.items[left].score < this.items[smallest].score) smallest = left;\n if (right < length && this.items[right].score < this.items[smallest].score) smallest = right;\n if (smallest === index) break;\n [this.items[index], this.items[smallest]] = [this.items[smallest], this.items[index]];\n index = smallest;\n }\n }\n\n values(): Array<{ index: number; score: number }> {\n return [...this.items].sort((a, b) => b.score - a.score);\n }\n}\n\nexport class MemoryVectorStore implements VectorStore {\n private records: VectorRecord[] = [];\n\n async add(records: VectorRecord[]): Promise<void> {\n this.records.push(...records);\n }\n\n async getAll(): Promise<VectorRecord[]> {\n return this.records.slice();\n }\n\n async clear(): Promise<void> {\n this.records = [];\n }\n\n async count(): Promise<number> {\n return this.records.length;\n }\n}\n\ninterface StoredVectorRecord {\n id: string;\n text?: string;\n metadata?: Record<string, unknown>;\n embedding: ArrayBuffer;\n}\n\nexport class IndexedDbVectorStore implements VectorStore {\n private dbPromise: Promise<IDBDatabase> | null = null;\n\n constructor(\n private readonly dbName = \"edgeinfer-matryoshka\",\n private readonly storeName = \"vectors\"\n ) {}\n\n private open(): Promise<IDBDatabase> {\n if (this.dbPromise) return this.dbPromise;\n if (typeof indexedDB === \"undefined\") {\n return Promise.reject(new Error(\"IndexedDB is unavailable in this environment\"));\n }\n this.dbPromise = new Promise<IDBDatabase>((resolve, reject) => {\n const request = indexedDB.open(this.dbName, 1);\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(this.storeName)) {\n db.createObjectStore(this.storeName, { keyPath: \"id\" });\n }\n };\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error ?? new Error(\"IndexedDB open failed\"));\n });\n return this.dbPromise;\n }\n\n async add(records: VectorRecord[]): Promise<void> {\n const db = await this.open();\n await new Promise<void>((resolve, reject) => {\n const transaction = db.transaction(this.storeName, \"readwrite\");\n const store = transaction.objectStore(this.storeName);\n for (const record of records) {\n const stored: StoredVectorRecord = {\n id: record.id,\n text: record.text,\n metadata: record.metadata,\n embedding: record.embedding.slice().buffer,\n };\n store.put(stored);\n }\n transaction.oncomplete = () => resolve();\n transaction.onerror = () => reject(transaction.error ?? new Error(\"IndexedDB write failed\"));\n transaction.onabort = () => reject(transaction.error ?? new Error(\"IndexedDB write aborted\"));\n });\n }\n\n async getAll(): Promise<VectorRecord[]> {\n const db = await this.open();\n return new Promise<VectorRecord[]>((resolve, reject) => {\n const transaction = db.transaction(this.storeName, \"readonly\");\n const store = transaction.objectStore(this.storeName);\n const request = store.getAll();\n request.onsuccess = () => {\n const records = (request.result as StoredVectorRecord[]).map((stored) => ({\n id: stored.id,\n text: stored.text,\n metadata: stored.metadata,\n embedding: new Float32Array(stored.embedding),\n }));\n resolve(records);\n };\n request.onerror = () => reject(request.error ?? new Error(\"IndexedDB read failed\"));\n });\n }\n\n async clear(): Promise<void> {\n const db = await this.open();\n await new Promise<void>((resolve, reject) => {\n const transaction = db.transaction(this.storeName, \"readwrite\");\n transaction.objectStore(this.storeName).clear();\n transaction.oncomplete = () => resolve();\n transaction.onerror = () => reject(transaction.error ?? new Error(\"IndexedDB clear failed\"));\n });\n }\n\n async count(): Promise<number> {\n const db = await this.open();\n return new Promise<number>((resolve, reject) => {\n const transaction = db.transaction(this.storeName, \"readonly\");\n const request = transaction.objectStore(this.storeName).count();\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error ?? new Error(\"IndexedDB count failed\"));\n });\n }\n\n close(): void {\n void this.dbPromise?.then((db) => db.close());\n this.dbPromise = null;\n }\n}\n\nexport class MatryoshkaIndex {\n readonly dimensions: number;\n readonly coarseDimension: number;\n readonly refineTopK: number;\n private store?: VectorStore;\n private ids: string[] = [];\n private texts: Array<string | undefined> = [];\n private metadata: Array<Record<string, unknown> | undefined> = [];\n private full: Float32Array = new Float32Array(0);\n private coarse: Int8Array = new Int8Array(0);\n private scales: Float32Array = new Float32Array(0);\n private size = 0;\n\n constructor(options: MatryoshkaOptions = {}) {\n this.dimensions = options.dimensions ?? 768;\n this.coarseDimension = options.coarseDimension ?? 64;\n this.refineTopK = options.refineTopK ?? 50;\n this.store = options.store;\n if (this.coarseDimension > this.dimensions) {\n throw new Error(\"coarseDimension cannot exceed dimensions\");\n }\n }\n\n get count(): number {\n return this.size;\n }\n\n async build(records: VectorRecord[], { persist = true } = {}): Promise<void> {\n if (records.length === 0) throw new Error(\"At least one record is required\");\n for (const record of records) {\n if (record.embedding.length !== this.dimensions) {\n throw new Error(\n `Record ${record.id} has ${record.embedding.length} dims; expected ${this.dimensions}`\n );\n }\n }\n\n this.ids = new Array(records.length);\n this.texts = new Array(records.length);\n this.metadata = new Array(records.length);\n this.full = new Float32Array(records.length * this.dimensions);\n this.coarse = new Int8Array(records.length * this.coarseDimension);\n this.scales = new Float32Array(records.length);\n this.size = records.length;\n\n for (let row = 0; row < records.length; row++) {\n const record = records[row];\n const normalized = l2Normalize(record.embedding, this.dimensions);\n this.ids[row] = record.id;\n this.texts[row] = record.text;\n this.metadata[row] = record.metadata;\n this.full.set(normalized, row * this.dimensions);\n\n const quantized = quantizeInt8(normalized, this.coarseDimension);\n this.coarse.set(quantized.data, row * this.coarseDimension);\n this.scales[row] = quantized.scale;\n }\n\n if (persist && this.store) {\n await this.store.clear();\n const normalizedRecords = records.map((record, row) => ({\n ...record,\n embedding: this.full.slice(row * this.dimensions, (row + 1) * this.dimensions),\n }));\n await this.store.add(normalizedRecords);\n }\n }\n\n static async load(store: VectorStore, options: MatryoshkaOptions = {}): Promise<MatryoshkaIndex> {\n const index = new MatryoshkaIndex({ ...options, store });\n const records = await store.getAll();\n await index.build(records, { persist: false });\n return index;\n }\n\n search(query: Float32Array, options: SearchOptions = {}): SearchResult[] {\n if (this.size === 0) throw new Error(\"Index is empty; call build() first\");\n const topK = options.topK ?? 10;\n const refine = options.refine ?? true;\n const coarseDimension = options.coarseDimension ?? this.coarseDimension;\n if (coarseDimension > this.coarseDimension) {\n throw new Error(\n `coarseDimension ${coarseDimension} exceeds the indexed stride ${this.coarseDimension}`\n );\n }\n const queryFull = l2Normalize(query, this.dimensions);\n const queryCoarse = quantizeInt8(queryFull, coarseDimension);\n const refineTopK = Math.max(\n topK,\n Math.min(this.refineTopK, options.refineTopK ?? this.refineTopK, this.size)\n );\n\n const heap = new TopKHeap(refineTopK);\n for (let row = 0; row < this.size; row++) {\n const offset = row * this.coarseDimension;\n let sum = 0;\n for (let i = 0; i < coarseDimension; i++) {\n sum += queryCoarse.data[i] * this.coarse[offset + i];\n }\n heap.push(row, sum * this.scales[row]);\n }\n\n let candidates: Array<{ index: number; score: number; coarseScore: number }> =\n heap.values().map((candidate) => ({ ...candidate, coarseScore: candidate.score }));\n if (refine) {\n candidates = candidates\n .map((candidate) => ({\n ...candidate,\n score: dot(\n queryFull,\n this.full.subarray(\n candidate.index * this.dimensions,\n (candidate.index + 1) * this.dimensions\n ),\n this.dimensions\n ),\n }))\n .sort((a, b) => b.score - a.score);\n }\n\n return candidates.slice(0, topK).map((candidate) => ({\n id: this.ids[candidate.index],\n text: this.texts[candidate.index],\n metadata: this.metadata[candidate.index],\n score: candidate.score,\n coarseScore: candidate.coarseScore,\n }));\n }\n\n exactSearchAtDimension(\n query: Float32Array,\n dimension: number,\n topK = 10\n ): Array<{ index: number; score: number }> {\n if (dimension > this.dimensions) throw new Error(\"dimension exceeds index dimensions\");\n const queryNormalized = truncateAndNormalize(query, dimension);\n const scored: Array<{ index: number; score: number }> = [];\n for (let row = 0; row < this.size; row++) {\n const vector = truncateAndNormalize(\n this.full.subarray(row * this.dimensions, (row + 1) * this.dimensions),\n dimension\n );\n scored.push({ index: row, score: dot(queryNormalized, vector, dimension) });\n }\n return scored.sort((a, b) => b.score - a.score).slice(0, topK);\n }\n\n recallAtK(\n queries: Float32Array[],\n groundTruth: string[][],\n dimension: number,\n topK = 10\n ): number {\n let hits = 0;\n let total = 0;\n for (let q = 0; q < queries.length; q++) {\n const expected = new Set(groundTruth[q].slice(0, topK));\n const candidates = this.exactSearchAtDimension(queries[q], dimension, topK);\n for (const candidate of candidates) {\n if (expected.has(this.ids[candidate.index])) hits++;\n }\n total += Math.min(topK, expected.size);\n }\n return total === 0 ? 0 : hits / total;\n }\n\n get idList(): readonly string[] {\n return this.ids;\n }\n}\n\nexport type EmbedFn = (text: string) => Promise<Float32Array> | Float32Array;\n\nexport async function embedMatryoshka(\n text: string,\n dimension: number,\n embed: EmbedFn\n): Promise<Float32Array> {\n const full = await embed(text);\n return truncateAndNormalize(full, dimension);\n}\n\nexport function createMatryoshkaEmbedder(embed: EmbedFn) {\n return (text: string, dimension = 768) => embedMatryoshka(text, dimension, embed);\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2024-2026 Soumya Debnath\n//\n// Speculative decoding with a small draft model and a larger target model.\n// The target verifies gamma draft tokens in one forward pass. Accepted tokens\n// keep their draft distribution; a rejection resamples from the residual\n// max(0, p_target - p_draft) and truncates both KV-cache states.\n\nexport interface ModelState {\n tokens: number[];\n /** Opaque KV-cache handle for cache-aware adapters. */\n cache?: unknown;\n}\n\nexport interface DecodeResult {\n state: ModelState;\n /**\n * One next-token distribution for each input position, plus one distribution\n * after the last input token. Length = tokens.length + 1. Calling decode()\n * with an empty token array returns the distribution after the current state.\n */\n logits: Float32Array[];\n}\n\nexport interface LanguageModel {\n readonly vocabSize: number;\n prefill(tokens: number[]): Promise<ModelState>;\n decode(state: ModelState, tokens: number[]): Promise<DecodeResult>;\n /**\n * Drop cache entries after `length` total tokens. Cache-aware adapters must\n * implement this; stateless models can just slice the token list.\n */\n truncate(state: ModelState, length: number): ModelState;\n}\n\nexport interface SpeculativeOptions {\n draft: LanguageModel;\n target: LanguageModel;\n gamma?: number;\n rng?: () => number;\n eosTokenId?: number;\n}\n\nexport interface SpeculativeStats {\n outputTokens: number;\n draftTokens: number;\n acceptedTokens: number;\n bonusTokens: number;\n rejectedTokens: number;\n targetCalls: number;\n draftCalls: number;\n acceptanceRate: number;\n targetCallsPerToken: number;\n elapsedMs: number;\n tokensPerSecond: number;\n}\n\nexport interface SpeculativeGenerationResult {\n tokens: number[];\n stats: SpeculativeStats;\n}\n\nexport class SpeculativeDecoder {\n readonly draft: LanguageModel;\n readonly target: LanguageModel;\n readonly gamma: number;\n private readonly rng: () => number;\n private readonly eosTokenId?: number;\n\n constructor(options: SpeculativeOptions) {\n if (options.draft.vocabSize !== options.target.vocabSize) {\n throw new Error(\"Draft and target models must share a vocabulary size\");\n }\n const gamma = options.gamma ?? 5;\n if (!Number.isInteger(gamma) || gamma < 1) {\n throw new Error(\"gamma must be a positive integer\");\n }\n this.draft = options.draft;\n this.target = options.target;\n this.gamma = gamma;\n this.rng = options.rng ?? Math.random;\n this.eosTokenId = options.eosTokenId;\n }\n\n async generate(\n prompt: number[],\n maxNewTokens = 64,\n { temperature = 1 }: { temperature?: number } = {}\n ): Promise<SpeculativeGenerationResult> {\n if (prompt.length === 0) throw new Error(\"prompt must not be empty\");\n if (maxNewTokens < 1) throw new Error(\"maxNewTokens must be positive\");\n if (temperature <= 0) throw new Error(\"temperature must be positive\");\n\n const started = performance.now();\n let draftState = await this.draft.prefill(prompt);\n let targetState = await this.target.prefill(prompt);\n\n const output: number[] = [];\n let draftTokens = 0;\n let acceptedTokens = 0;\n let bonusTokens = 0;\n let rejectedTokens = 0;\n let targetCalls = 0;\n let draftCalls = 0;\n\n while (output.length < maxNewTokens) {\n const gamma = Math.min(this.gamma, maxNewTokens - output.length);\n const draft = await this.draftBatch(draftState, gamma, temperature, draftCalls);\n draftState = draft.state;\n draftCalls = draft.calls;\n draftTokens += draft.tokens.length;\n\n const prefixLength = targetState.tokens.length;\n const verification = await this.target.decode(targetState, draft.tokens);\n targetCalls++;\n targetState = verification.state;\n\n let rejected = false;\n for (let i = 0; i < draft.tokens.length; i++) {\n const token = draft.tokens[i];\n const q = draft.probabilities[i][token];\n const p = probability(verification.logits[i], token, temperature);\n if (this.rng() < Math.min(1, p / q)) {\n output.push(token);\n acceptedTokens++;\n if (token === this.eosTokenId || output.length >= maxNewTokens) break;\n continue;\n }\n\n const residual = residualDistribution(\n verification.logits[i],\n draft.probabilities[i],\n temperature\n );\n const replacement = sample(residual, this.rng());\n output.push(replacement);\n rejectedTokens++;\n rejected = true;\n\n const keep = prefixLength + i;\n targetState = this.target.truncate(targetState, keep);\n draftState = this.draft.truncate(draftState, keep);\n const targetAdvance = await this.target.decode(targetState, [replacement]);\n targetCalls++;\n targetState = targetAdvance.state;\n const draftAdvance = await this.draft.decode(draftState, [replacement]);\n draftCalls++;\n draftState = draftAdvance.state;\n break;\n }\n\n if (rejected) continue;\n if (output.length >= maxNewTokens || output[output.length - 1] === this.eosTokenId) break;\n\n const bonusDistribution = softmax(\n verification.logits[draft.tokens.length],\n temperature\n );\n const bonus = sample(bonusDistribution, this.rng());\n output.push(bonus);\n bonusTokens++;\n const targetAdvance = await this.target.decode(targetState, [bonus]);\n targetCalls++;\n targetState = targetAdvance.state;\n const draftAdvance = await this.draft.decode(draftState, [bonus]);\n draftCalls++;\n draftState = draftAdvance.state;\n if (bonus === this.eosTokenId) break;\n }\n\n const elapsedMs = performance.now() - started;\n const stats: SpeculativeStats = {\n outputTokens: output.length,\n draftTokens,\n acceptedTokens,\n bonusTokens,\n rejectedTokens,\n targetCalls,\n draftCalls,\n acceptanceRate: draftTokens === 0 ? 0 : acceptedTokens / draftTokens,\n targetCallsPerToken: output.length === 0 ? 0 : targetCalls / output.length,\n elapsedMs,\n tokensPerSecond: elapsedMs === 0 ? 0 : (output.length / elapsedMs) * 1000,\n };\n return { tokens: output, stats };\n }\n\n private async draftBatch(\n state: ModelState,\n gamma: number,\n temperature: number,\n calls: number\n ): Promise<{ state: ModelState; tokens: number[]; probabilities: Float32Array[]; calls: number }> {\n let current = state;\n const tokens: number[] = [];\n const probabilities: Float32Array[] = [];\n\n const first = await this.draft.decode(current, []);\n calls++;\n let nextDistribution = first.logits[0];\n for (let i = 0; i < gamma; i++) {\n const distribution = softmax(nextDistribution, temperature);\n const token = sample(distribution, this.rng());\n tokens.push(token);\n probabilities.push(distribution);\n const advanced = await this.draft.decode(current, [token]);\n calls++;\n current = advanced.state;\n nextDistribution = advanced.logits[advanced.logits.length - 1];\n }\n return { state: current, tokens, probabilities, calls };\n }\n}\n\nexport function softmax(logits: Float32Array, temperature = 1): Float32Array {\n let max = -Infinity;\n for (let i = 0; i < logits.length; i++) max = Math.max(max, logits[i]);\n const output = new Float32Array(logits.length);\n let sum = 0;\n for (let i = 0; i < logits.length; i++) {\n const value = Math.exp((logits[i] - max) / temperature);\n output[i] = value;\n sum += value;\n }\n if (sum === 0) return output;\n for (let i = 0; i < output.length; i++) output[i] /= sum;\n return output;\n}\n\nexport function probability(logits: Float32Array, token: number, temperature = 1): number {\n return softmax(logits, temperature)[token] ?? 0;\n}\n\nexport function sample(distribution: Float32Array, random: number): number {\n let cumulative = 0;\n for (let i = 0; i < distribution.length; i++) {\n cumulative += distribution[i];\n if (random <= cumulative) return i;\n }\n return distribution.length - 1;\n}\n\nexport function residualDistribution(\n targetLogits: Float32Array,\n draftProbabilities: Float32Array,\n temperature = 1\n): Float32Array {\n const p = softmax(targetLogits, temperature);\n const q = draftProbabilities;\n const residual = new Float32Array(p.length);\n let sum = 0;\n for (let i = 0; i < p.length; i++) {\n const value = Math.max(0, p[i] - q[i]);\n residual[i] = value;\n sum += value;\n }\n if (sum === 0) return p;\n for (let i = 0; i < residual.length; i++) residual[i] /= sum;\n return residual;\n}\n\nexport type LogitPolicy = (tokens: number[]) => Float32Array;\n\n/** Deterministic mock used by tests and the throughput benchmark. */\nexport class MockLanguageModel implements LanguageModel {\n constructor(\n private readonly policy: LogitPolicy,\n readonly vocabSize: number,\n private readonly latencyMs = 0\n ) {}\n\n async prefill(tokens: number[]): Promise<ModelState> {\n await delay(this.latencyMs);\n return { tokens: tokens.slice() };\n }\n\n async decode(state: ModelState, tokens: number[]): Promise<DecodeResult> {\n await delay(this.latencyMs);\n const logits: Float32Array[] = [];\n for (let i = 0; i <= tokens.length; i++) {\n logits.push(this.policy([...state.tokens, ...tokens.slice(0, i)]));\n }\n return { state: { tokens: [...state.tokens, ...tokens] }, logits };\n }\n\n truncate(state: ModelState, length: number): ModelState {\n return { ...state, tokens: state.tokens.slice(0, length), cache: undefined };\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n if (ms <= 0) return Promise.resolve();\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","// SPDX-License-Identifier: MIT\n// Copyright (c) 2024-2026 Soumya Debnath\n//\n// ONNX Runtime Web adapter for causal language models. This adapter recomputes\n// the full token sequence on each call, so it is correctness-first and works\n// with standard exports that accept input_ids/attention_mask and return logits.\n// Cache-aware adapters can implement LanguageModel.truncate and store KV tensors\n// in ModelState.cache without changing the speculative decoder.\n\nimport * as ort from 'onnxruntime-web';\nimport { LanguageModel, ModelState, DecodeResult } from './speculative';\n\nexport interface OnnxCausalOptions {\n inputIdsName?: string;\n attentionMaskName?: string;\n positionIdsName?: string;\n logitsName?: string;\n}\n\nexport class OnnxCausalLM implements LanguageModel {\n readonly vocabSize: number;\n private readonly inputIdsName: string;\n private readonly attentionMaskName: string;\n private readonly positionIdsName?: string;\n private readonly logitsName: string;\n\n constructor(\n private readonly session: ort.InferenceSession,\n vocabSize: number,\n options: OnnxCausalOptions = {}\n ) {\n if (!Number.isInteger(vocabSize) || vocabSize < 1) {\n throw new Error('vocabSize must be a positive integer');\n }\n this.vocabSize = vocabSize;\n this.inputIdsName = options.inputIdsName ?? 'input_ids';\n this.attentionMaskName = options.attentionMaskName ?? 'attention_mask';\n this.positionIdsName = options.positionIdsName;\n this.logitsName = options.logitsName ?? 'logits';\n }\n\n async prefill(tokens: number[]): Promise<ModelState> {\n if (tokens.length === 0) throw new Error('prefill requires a non-empty prompt');\n return { tokens: tokens.slice() };\n }\n\n async decode(state: ModelState, tokens: number[]): Promise<DecodeResult> {\n const all = [...state.tokens, ...tokens];\n if (all.length === 0) throw new Error('decode requires at least one token');\n if (state.tokens.length === 0) throw new Error('decode requires a prefilled state');\n\n const feeds: Record<string, ort.Tensor> = {\n [this.inputIdsName]: new ort.Tensor(\n 'int64',\n BigInt64Array.from(all, (token) => BigInt(token)),\n [1, all.length]\n ),\n [this.attentionMaskName]: new ort.Tensor(\n 'int64',\n BigInt64Array.from({ length: all.length }, () => 1n),\n [1, all.length]\n ),\n };\n if (this.positionIdsName) {\n feeds[this.positionIdsName] = new ort.Tensor(\n 'int64',\n BigInt64Array.from(all, (_, index) => BigInt(index)),\n [1, all.length]\n );\n }\n\n const outputs = await this.session.run(feeds);\n const tensor = outputs[this.logitsName];\n if (!tensor) {\n throw new Error(`ONNX model did not return \"${this.logitsName}\"`);\n }\n const dims = tensor.dims;\n const vocab = dims[dims.length - 1];\n if (vocab !== this.vocabSize) {\n throw new Error(\n `ONNX logits vocabulary ${vocab} does not match configured ${this.vocabSize}`\n );\n }\n const data = tensor.data as Float32Array;\n const seq = all.length;\n const expected = seq * vocab;\n if (data.length < expected) {\n throw new Error(`ONNX logits tensor is too small (${data.length} < ${expected})`);\n }\n\n const start = state.tokens.length - 1;\n const logits: Float32Array[] = [];\n for (let i = 0; i <= tokens.length; i++) {\n const position = start + i;\n const offset = dims.length === 3 ? position * vocab : position * vocab;\n logits.push(new Float32Array(data.subarray(offset, offset + vocab)));\n }\n return { state: { tokens: all }, logits };\n }\n\n truncate(state: ModelState, length: number): ModelState {\n return { tokens: state.tokens.slice(0, length) };\n }\n}\n"],"mappings":"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","names":["buffer","session","size","ort","sample","targetAdvance","draftAdvance","ort"]}
|