Spaces:
Running
Running
Download worker.js from mrfakename/kumo-tabular-webgpu: direct link, hf CLI and curl.
- Browser
- Download file 3.24 kB
-
https://huggingface.co/spaces/mrfakename/kumo-tabular-webgpu/resolve/main/worker.js
- Command line
-
hf download hf://spaces/mrfakename/kumo-tabular-webgpu/worker.js
-
curl -L -o worker.js https://huggingface.co/spaces/mrfakename/kumo-tabular-webgpu/resolve/main/worker.js
3.24 kB
| import * as ort from "https://cdn.jsdelivr.net/npm/onnxruntime-web@1.30.0/dist/ort.webgpu.bundle.min.mjs"; | |
| import { predict } from "./predict.js"; | |
| const REPO = "https://huggingface.co/mrfakename/Kumo-Tabular-ONNX/resolve/main/onnx"; | |
| ort.env.wasm.wasmPaths = "https://cdn.jsdelivr.net/npm/onnxruntime-web@1.30.0/dist/"; | |
| ort.env.wasm.numThreads = self.crossOriginIsolated ? Math.min(4, navigator.hardwareConcurrency || 1) : 1; | |
| const sessions = new Map(); | |
| const post = (type, extra) => self.postMessage({ type, ...extra }); | |
| async function fetchModel(url, label) { | |
| let cache = null; | |
| try { cache = await caches.open("kumo-tabular-onnx-v1"); } catch {} | |
| const hit = cache && (await cache.match(url)); | |
| if (hit) return new Uint8Array(await hit.arrayBuffer()); | |
| const res = await fetch(url); | |
| if (!res.ok) throw new Error(`Download failed (${res.status}) for ${label}`); | |
| const total = +res.headers.get("content-length") || 0; | |
| const reader = res.body.getReader(); | |
| const parts = []; let got = 0; | |
| for (;;) { | |
| const { done, value } = await reader.read(); | |
| if (done) break; | |
| parts.push(value); got += value.length; | |
| post("status", { message: `Downloading ${label}… ${(got / 1e6).toFixed(0)}${total ? ` / ${(total / 1e6).toFixed(0)}` : ""} MB`, progress: total ? got / total : null }); | |
| } | |
| const buf = new Uint8Array(got); let o = 0; | |
| for (const p of parts) { buf.set(p, o); o += p.length; } | |
| if (cache) { try { await cache.put(url, new Response(buf)); } catch {} } | |
| return buf; | |
| } | |
| async function getSession(size, task, backend) { | |
| const key = `${size}_${task}_${backend}`; | |
| if (sessions.has(key)) return sessions.get(key); | |
| // keep at most one session alive to bound memory | |
| for (const [k, s] of sessions) { try { await s.release(); } catch {} sessions.delete(k); } | |
| const label = `${size} ${task} model`; | |
| const bytes = await fetchModel(`${REPO}/${size}_${task}.onnx`, label); | |
| post("status", { message: `Initializing ${label} on ${backend.toUpperCase()}…`, progress: null }); | |
| const providers = backend === "webgpu" ? ["webgpu", "wasm"] : ["wasm"]; | |
| const session = await ort.InferenceSession.create(bytes, { executionProviders: providers, graphOptimizationLevel: "all" }); | |
| sessions.set(key, session); | |
| return session; | |
| } | |
| self.onmessage = async ({ data }) => { | |
| if (data.type !== "predict") return; | |
| let backend = data.backend; | |
| if (backend === "webgpu" && !(navigator.gpu && (await navigator.gpu.requestAdapter().catch(() => null)))) backend = "wasm"; | |
| try { | |
| const t0 = performance.now(); | |
| const res = await predict({ | |
| ort, ctx: data.ctx, qry: data.qry, target: data.target, task: data.task, | |
| numEstimators: data.numEstimators, | |
| getSession: (task) => getSession(data.size, task, backend), | |
| onProgress: (message, progress) => post("status", { message, progress }), | |
| }); | |
| const secs = ((performance.now() - t0) / 1000).toFixed(1); | |
| post("result", { | |
| ...res, | |
| summary: `${res.task} · ${data.size} model on ${backend.toUpperCase()} · ${res.nContext} context rows · ${res.nQuery} predicted · ${res.nFeatures} features · ${secs}s`, | |
| }); | |
| } catch (e) { | |
| console.error(e); | |
| post("error", { message: `Error: ${e.message || e}` }); | |
| } | |
| }; | |