-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
System Info
@huggingface/transformers@4.0.0-next.3onnxruntime-web@1.25.0-dev- Vite 7.3.1
- Chrome (latest)
- macOS
Environment/Platform
- Website/web-app
- Browser extension
- Server-side (e.g., Node.js, Deno, Bun)
- Desktop app (e.g., Electron)
- Other (e.g., VSCode extension)
Description
In v4, backends/onnx.js unconditionally sets wasmPaths to cdn.jsdelivr.net:
onnxEnv.wasm.wasmPaths = `https://cdn.jsdelivr.net/npm/onnxruntime-web@${ORT_VERSION}/dist/`;This causes onnxruntime-web to construct Workers from CDN URLs, which browsers block with a CORS error when the page is served from localhost (or any non-CDN origin):
Failed to construct 'Worker': Script at 'https://cdn.jsdelivr.net/npm/onnxruntime-web@1.25.0-dev/dist/ort-wasm-simd-threaded.asyncify.mjs'
cannot be accessed from origin 'http://localhost:5175'.
Additionally, even when serving the ORT files locally, the COEP requirement (Cross-Origin-Embedder-Policy: require-corp) for SharedArrayBuffer means ALL sub-resources need proper Cross-Origin-Resource-Policy headers — which CDN-served files don't have in a local dev context.
v3 behavior (worked correctly)
v3.x did not set wasmPaths, allowing onnxruntime-web to resolve WASM files and Worker scripts relative to the importing script. Bundlers like Vite serve these naturally from localhost, so everything was same-origin — no CORS issues.
Suggested Fix
Only default to CDN wasmPaths if the user hasn't already configured a custom path and the environment isn't a local dev server:
// Only default to CDN if user hasn't overridden and not on localhost
if (!onnxEnv.wasm.wasmPaths) {
const isLocalDev = typeof location !== 'undefined' &&
(location.hostname === 'localhost' || location.hostname === '127.0.0.1');
if (!isLocalDev) {
onnxEnv.wasm.wasmPaths = `https://cdn.jsdelivr.net/npm/onnxruntime-web@${ORT_VERSION}/dist/`;
}
}Or, better yet: revert to v3 behavior and let onnxruntime-web resolve paths naturally. Only use CDN as an explicit opt-in via env.backends.onnx.wasm.wasmPaths.
Current Workaround
Override wasmPaths after import and serve ORT dist files locally (e.g., via vite-plugin-static-copy):
import { env } from '@huggingface/transformers';
// Point to locally-served ORT files instead of CDN
env.backends.onnx.wasm.wasmPaths = '/ort/';Vite config (using vite-plugin-static-copy):
import { viteStaticCopy } from 'vite-plugin-static-copy';
// Also need cross-origin isolation headers for SharedArrayBuffer
function crossOriginIsolation() {
return {
name: 'cross-origin-isolation',
configureServer(server) {
server.middlewares.use((_req, res, next) => {
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
res.setHeader('Cross-Origin-Resource-Policy', 'same-origin');
next();
});
},
};
}
export default defineConfig({
plugins: [
crossOriginIsolation(),
viteStaticCopy({
targets: [{ src: '<path-to-onnxruntime-web>/dist/*', dest: 'ort' }],
}),
],
});Reproduction
- Create a Vite project
- Install
@huggingface/transformers@4.0.0-next.3 - In a Web Worker, run:
import { AutoModelForVision2Seq, env } from '@huggingface/transformers';
env.allowLocalModels = false;
env.useBrowserCache = true;
const model = await AutoModelForVision2Seq.from_pretrained(
'HuggingFaceTB/SmolVLM-500M-Instruct',
{ dtype: 'q4f16', device: 'webgpu' }
);- Browser console shows:
Failed to construct 'Worker'CORS error