Better tests and more user feedback while doing transcription; WIP.

This commit is contained in:
Lucas Winther
2026-07-14 14:44:01 +02:00
parent 18acead43c
commit be82ecfe57
19 changed files with 447 additions and 138 deletions
+52 -3
View File
@@ -10,8 +10,10 @@
export type InferenceDevice = "webgpu" | "wasm" | "webnn";
/**
* What the UI may request. "auto" (the default) lets the worker probe
* `navigator.gpu` and pick WebGPU with automatic WASM fallback (D-004).
* What the UI may request. "auto" (the default) lets the worker probe the
* available backends and pick in priority order WebNN → WebGPU → WASM
* (D-004/D-017), with automatic fallback down the same chain if pipeline
* creation fails on the picked device.
*/
export type DevicePreference = InferenceDevice | "auto";
@@ -79,7 +81,7 @@ export type UiToWorkerMessage = LoadMessage | TranscribeMessage;
* Model download / initialization progress. Mirrors the Transformers.js
* `progress_callback` events we care about; `status: "ready"` marks the end
* of a successful load and reports the backend that actually got selected
* (after WebGPU detection / fallback, D-004).
* (after device detection / fallback, D-004, D-017).
*/
export type LoadProgressMessage =
| { type: "load-progress"; status: "initiate"; file: string }
@@ -135,6 +137,53 @@ export type WorkerToUiMessage =
| ResultMessage
| ErrorMessage;
// ---------------------------------------------------------------------------
// Device selection policy (D-004, D-017) — pure so it is unit-testable; the
// worker probes the browser capabilities and this decides the attempt order.
// ---------------------------------------------------------------------------
/** What the worker's capability probe found (see inference.worker.ts). */
export interface DeviceCapabilities {
/** `navigator.ml` exists (WebNN). */
webnn: boolean;
/** `navigator.gpu.requestAdapter()` returned an adapter (WebGPU). */
webgpu: boolean;
}
/**
* Resolve a device preference against probed capabilities into the ordered
* list of devices to attempt pipeline creation on. The first entry is the
* selected device; later entries are automatic fallbacks for when creation
* throws (driver quirks, unsupported ops, out-of-memory). Never empty — WASM
* is always the last resort.
*
* - "auto": WebNN → WebGPU → WASM (D-017), skipping backends the probe ruled
* out, so an auto-detected WebNN that fails still tries WebGPU before WASM.
* - Explicit "webnn"/"webgpu": that device (if available) → WASM. An explicit
* choice deliberately does not detour through the other accelerator.
* - "wasm": WASM only.
*/
export function deviceAttempts(
preference: DevicePreference,
capabilities: DeviceCapabilities,
): InferenceDevice[] {
switch (preference) {
case "wasm":
return ["wasm"];
case "webgpu":
return capabilities.webgpu ? ["webgpu", "wasm"] : ["wasm"];
case "webnn":
return capabilities.webnn ? ["webnn", "wasm"] : ["wasm"];
case "auto": {
const attempts: InferenceDevice[] = [];
if (capabilities.webnn) attempts.push("webnn");
if (capabilities.webgpu) attempts.push("webgpu");
attempts.push("wasm");
return attempts;
}
}
}
// ---------------------------------------------------------------------------
// Runtime guards (postMessage data arrives untyped)
// ---------------------------------------------------------------------------