Skip to content

[Web] No available backend found for WebGL (web worker) #26611

@KevinCepria

Description

@KevinCepria

Describe the issue

Im instantiating my ORT session inside a web worker. Tried using the webgl execution provider but it this error is being thrown:

Error: no available backend found. ERR: [webgl] backend not found. at Qi (http://localhost:3000/static/js/vendors-node_modules_pmmmwh_react-refresh-webpack-plugin_lib_runtime_RefreshUtils_js-node_mod-02c417.chunk.js:389:21) at async e.create (http://localhost:3000/static/js/vendors-node_modules_pmmmwh_react-refresh-webpack-plugin_lib_runtime_RefreshUtils_js-node_mod-02c417.chunk.js:996:22) at async Promise.all (index 0) at async __webpack_modules__../src/workers/onnxWorker.ts.self.onmessage (http://localhost:3000/static/js/src_workers_onnxWorker_ts.chunk.js:104:9)

Previously I was using 'wasm' which works fine but the wasm file is just too big to load in my application

To reproduce

ORT version: 1.23
Browser: Chrome 139.0.7258.127 (Official Build) (64-bit)
Frame work: Create React App
Webpack version: 5.98

Im using CRACO in overriding some webpack configurations:

module.exports = {
  webpack: {
    configure: (webpackConfig, { env, paths }) => {
      webpackConfig.target = "webworker";
      webpackConfig.output = {
        ...webpackConfig.output,
        publicPath: 'auto',
      };
      return webpackConfig;
    },
  },
};

Worker code:

/// <reference lib="webworker" />
import * as ort from 'onnxruntime-web';

type InitMessage = { type: 'init'; data: [ArrayBuffer, ArrayBuffer] };
type ProcessMessage = { type: 'process'; data: any };
type ResetSilero = { type: 'reset-silero' };

/* Silero ONNX variables */
let sileroSession: ort.InferenceSession | null = null;
const MIN_SPEECH_FRAMES = 3;
const POSITIVE_SPEECH_THRESHOLD = 0.65;
const REDEMPTION_FRAMES = 5;

let h: ort.Tensor | null = null;
let c: ort.Tensor | null = null;
let sr: ort.Tensor | null = null;

let redemptionCounter = 0;
let speechFrameCount = 0;
let speechDetected = false;

const zeroes = Array(2 * 64).fill(0);

function handleInit(data: [ArrayBuffer]) {
    const [SileroModelBuffer] = data;
    return Promise.all([
        ort.InferenceSession.create(SileroModelBuffer, { executionProviders: ['webgl'] }),
    ]).then(([silero]) => {
        sileroSession = silero;

        sr = new ort.Tensor('int64', [16000n]);
        h = new ort.Tensor('float32', zeroes, [2, 1, 64]);
        c = new ort.Tensor('float32', zeroes, [2, 1, 64]);

        self.postMessage({ type: 'init-complete' });
    });
}

async function handleProcess(data: any) {
    if (!sileroSession) {
        self.postMessage({ type: 'error', error: 'Session not initialized' });
        return;
    }

    const { pcmData, isVadActive } = data;

    if (!isVadActive) return;

    const input = new ort.Tensor('float32', pcmData, [1, pcmData.length]);
    const inputs: Record<string, ort.Tensor> = { input, h: h!, c: c!, sr: sr! };
    const out = await sileroSession.run(inputs);
    h = out['hn'];
    c = out['cn'];
    const outArr = out['output']?.data as Float32Array | undefined;
    const isSpeech = outArr ? outArr[0] : 0;
    const isSpeechPositive = isSpeech > POSITIVE_SPEECH_THRESHOLD;
    if (isSpeechPositive) {
        redemptionCounter = 0;
        speechFrameCount++;
    }
    if (isSpeechPositive && speechFrameCount >= MIN_SPEECH_FRAMES) {
        speechDetected = true;
    }
    if (!isSpeechPositive && ++redemptionCounter === REDEMPTION_FRAMES) {
        speechFrameCount = 0;
        redemptionCounter = 0;
        speechDetected = false;
    }

    self.postMessage({ type: 'silero-processed', data: speechDetected });
}

function handleResetSilero() {
    h = new ort.Tensor('float32', zeroes, [2, 1, 64]);
    c = new ort.Tensor('float32', zeroes, [2, 1, 64]);

    speechDetected = false;
    redemptionCounter = 0;
    speechFrameCount = 0;
}
self.onmessage = async (event: MessageEvent<InitMessage | ProcessMessage | ResetSilero>) => {
    try {
        const { type, data } = event.data as any;
        switch (type) {
            case 'init':
                await handleInit(data);
                break;
            case 'process':
                await handleProcess(data);
                break;

            case 'reset-silero':
                handleResetSilero();
                break;
            default:
                self.postMessage({ type: 'error', error: 'Unknown message type' });
        }
    } catch (err: any) {
        self.postMessage({ type: 'error', error: err?.message ?? String(err) });
    }
};

Urgency

No response

ONNX Runtime Installation

Released Package

ONNX Runtime Version or Commit ID

1.23

Execution Provider

'webgl' (WebGL)

Metadata

Metadata

Assignees

No one assigned

    Labels

    platform:webissues related to ONNX Runtime web; typically submitted using template

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions